integration_pal 0.1.6 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +87 -26
- data/app/controllers/integration_pal/application_controller.rb +11 -3
- data/app/controllers/integration_pal/saml_controller.rb +69 -0
- data/config/routes.rb +6 -0
- data/lib/generators/integration_pal/install/install_generator.rb +11 -6
- data/lib/integration_pal.rb +2 -1
- data/lib/integration_pal/engine.rb +0 -2
- data/lib/integration_pal/version.rb +1 -1
- metadata +59 -62
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +0 -2405
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74caae0c072309e715b66419e74685509269ea75
|
4
|
+
data.tar.gz: 4091c879c8b127dc76941f33826b69747f06511e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebd076d4c5f3e5d5a72babca42402fedf3f558d3696f9af342edae583dace2642c4aef323a1a352d6b25f4d9fdd156ca92bdabfffc7181a15541c7f401d1868f
|
7
|
+
data.tar.gz: '0987932589a5431135b3625f491f01df1ce6d08ec3ed481c2584579319092e58fd4b1f775694fb7862670a885c796263b3973c1416d753d1ac1decc2c9e562f9'
|
data/README.md
CHANGED
@@ -4,44 +4,104 @@ This engine is meant to contain the elements of big_sis that can be shared acros
|
|
4
4
|
- job starting
|
5
5
|
- job monitoring
|
6
6
|
- error capturing
|
7
|
-
-
|
7
|
+
- Okta SAML2 authentication
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
1) Create an active job
|
11
11
|
`bin/rails generate job example_job`
|
12
12
|
|
13
13
|
## Installation
|
14
|
-
Add
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
1. Add `integration_pal` to your application's Gemfile:
|
15
|
+
```ruby
|
16
|
+
gem 'integration_pal'
|
17
|
+
```
|
18
|
+
|
19
|
+
And install the bundle:
|
20
|
+
```bash
|
21
|
+
$ bundle install
|
22
|
+
```
|
23
|
+
---
|
24
|
+
Or install the Gem manually:
|
25
|
+
```bash
|
26
|
+
$ gem install integration_pal
|
27
|
+
```
|
28
|
+
2. Define Environment variables
|
29
|
+
```bash
|
30
|
+
ENCRYPTION_KEY=... # must be 32 chars
|
31
|
+
SALT_KEY=... # must be 32 chars
|
32
|
+
|
33
|
+
OKTA_APP=okta_app_key
|
34
|
+
OKTA_ID=xxxxxxxxxxx # Usually Base64
|
35
|
+
SAML_DOMAIN=https://example-app-test.herokuapp.com/
|
36
|
+
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
|
37
|
+
```
|
38
|
+
|
39
|
+
3. Generate template files for your project:
|
40
|
+
```
|
41
|
+
$ bundle exec rails g integration_pal:install
|
42
|
+
```
|
43
|
+
|
44
|
+
4. Set active job
|
45
|
+
config.active_job.queue_adapter = :sidekiq # If you are using sidekiq
|
19
46
|
|
20
|
-
|
21
|
-
|
22
|
-
|
47
|
+
4. Configure app.
|
48
|
+
Include `sp_metadata.xml[.erb]` in `config/saml`:
|
49
|
+
```xml
|
50
|
+
<?xml version="1.0"?>
|
51
|
+
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="<%= ENV['SAML_AUDIENCE'] || URI.join(ENV['SAML_DOMAIN'], saml2_meta_path) %>">
|
52
|
+
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
53
|
+
<md:AssertionConsumerService Location="<%= URI.join(ENV['SAML_DOMAIN'], saml2_login_path) %>" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" index="0"/>
|
54
|
+
</md:SPSSODescriptor>
|
55
|
+
</md:EntityDescriptor>
|
56
|
+
```
|
57
|
+
|
58
|
+
Also include `idp_metadata.xml[.erb]` in `config/saml`:
|
59
|
+
```xml
|
60
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
61
|
+
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/<%= ENV['OKTA_ID'] %>">
|
62
|
+
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
63
|
+
<md:KeyDescriptor use="signing">
|
64
|
+
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
65
|
+
<ds:X509Data>
|
66
|
+
<ds:X509Certificate>
|
67
|
+
{{ INSERT OKTA CERTIFICATE HERE }}
|
68
|
+
</ds:X509Certificate>
|
69
|
+
</ds:X509Data>
|
70
|
+
</ds:KeyInfo>
|
71
|
+
</md:KeyDescriptor>
|
72
|
+
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
|
73
|
+
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
|
74
|
+
<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"/>
|
75
|
+
<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"/>
|
76
|
+
</md:IDPSSODescriptor>
|
77
|
+
</md:EntityDescriptor>
|
78
|
+
```
|
79
|
+
|
80
|
+
Metadata file names can be overriden from within an initializer:
|
81
|
+
```ruby
|
82
|
+
IntegrationPal.saml_idp_metadata = 'idp_metadata.xml'
|
83
|
+
IntegrationPal.saml_sp_metadata = 'sp_metadata.xml'
|
84
|
+
```
|
85
|
+
|
86
|
+
To validate or begin Okta authentication within a controller, use:
|
87
|
+
```ruby
|
88
|
+
session[:saml_username] ||= ENV['USER'] if Rails.env.in?(%w(development test))
|
89
|
+
redirect_to saml2_login_url unless session[:saml_username]
|
90
|
+
```
|
91
|
+
|
92
|
+
### Deploying to Heroku
|
93
|
+
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:
|
23
94
|
```
|
24
|
-
|
25
|
-
Or install it yourself as:
|
26
|
-
```bash
|
27
|
-
$ gem install integration_pal
|
95
|
+
libxmlsec1-dev
|
28
96
|
```
|
29
|
-
|
30
|
-
1) SET ENV VARS
|
31
|
-
ENV['ENCRYPTION_KEY'] # this must be 32 chars
|
32
|
-
ENV['SALT_KEY'] # this must be 32 chars
|
33
|
-
|
34
|
-
2) run `bundle exec rails g integration_pal:install`
|
35
|
-
|
36
|
-
3)set active job
|
37
|
-
config.active_job.queue_adapter = :sidekiq # If you are using sidekiq
|
97
|
+
! - Double check this if Heroku fails to build Gem native extensions for `nokogiri-xmlsec-instructure` during deployment.
|
38
98
|
|
39
99
|
## License
|
40
100
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
101
|
|
42
|
-
##
|
43
|
-
|
44
|
-
|
102
|
+
## Example API Request
|
103
|
+
Note how we sign the request using ApiAuth
|
104
|
+
```ruby
|
45
105
|
require "uri"
|
46
106
|
require "net/https"
|
47
107
|
require "time"
|
@@ -71,4 +131,5 @@ request.body = {
|
|
71
131
|
ApiAuth.sign!(request, access_key_id, secret_access_key)
|
72
132
|
|
73
133
|
response = http.request(request)
|
74
|
-
puts response.body
|
134
|
+
puts response.body
|
135
|
+
```
|
@@ -1,8 +1,16 @@
|
|
1
|
-
require "rack-cas-rails"
|
2
|
-
|
3
1
|
module IntegrationPal
|
4
2
|
class ApplicationController < ActionController::Base
|
5
3
|
protect_from_forgery with: :exception
|
6
|
-
before_action :
|
4
|
+
before_action :require_user, unless: :skip_authentication?
|
5
|
+
|
6
|
+
def skip_authentication?
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
|
10
|
+
def require_user
|
11
|
+
# pretend to be logged in; you can still go directly to /login if you want to test the SAML flow
|
12
|
+
session[:saml_username] ||= ENV['USER'] if Rails.env.in?(%w(development test))
|
13
|
+
redirect_to saml2_login_url unless session[:saml_username]
|
14
|
+
end
|
7
15
|
end
|
8
16
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module IntegrationPal
|
2
|
+
class SamlController < ApplicationController
|
3
|
+
class << self
|
4
|
+
def parse_meta_file(filename)
|
5
|
+
possible_names = ['.erb', ''].map { |ext| filename+ext }
|
6
|
+
possible_paths = []
|
7
|
+
|
8
|
+
['config/saml', 'config'].each do |prefix|
|
9
|
+
possible_names.each do |filename|
|
10
|
+
possible_paths << Rails.root.join(prefix, filename)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
meta_path = possible_paths.find &:exist?
|
15
|
+
|
16
|
+
meta_file = File.read(meta_path)
|
17
|
+
if meta_path.extname == '.erb'
|
18
|
+
meta_file = ERB.new(meta_file).result(ERBContext.new.get_binding)
|
19
|
+
end
|
20
|
+
SAML2::Entity.parse(meta_file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def idp_metadata
|
24
|
+
@idp_metadata ||= parse_meta_file(IntegrationPal.saml_idp_metadata)
|
25
|
+
end
|
26
|
+
|
27
|
+
def sp_metadata
|
28
|
+
@sp_metadata ||= parse_meta_file(IntegrationPal.saml_sp_metadata)
|
29
|
+
end
|
30
|
+
|
31
|
+
class ERBContext
|
32
|
+
include Rails.application.routes.url_helpers
|
33
|
+
|
34
|
+
def get_binding
|
35
|
+
binding
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protect_from_forgery except: [:create]
|
41
|
+
|
42
|
+
def skip_authentication?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def new
|
47
|
+
authn_request = self.class.sp_metadata.initiate_authn_request(self.class.idp_metadata)
|
48
|
+
redirect_to SAML2::Bindings::HTTPRedirect.encode(authn_request)
|
49
|
+
end
|
50
|
+
|
51
|
+
def create
|
52
|
+
response, _relay_state = SAML2::Bindings::HTTP_POST.decode(request.request_parameters)
|
53
|
+
unless self.class.sp_metadata.valid_response?(response, self.class.idp_metadata)
|
54
|
+
logger.error("Failed to validate SAML response: #{response.errors}")
|
55
|
+
raise ActionController::RoutingError.new('Not Found')
|
56
|
+
end
|
57
|
+
|
58
|
+
reset_session
|
59
|
+
session[:saml_username] = response.assertions.first.subject.name_id.id
|
60
|
+
logger.info("Logged in using SAML2 as #{session[:saml_username]}")
|
61
|
+
|
62
|
+
redirect_to root_url
|
63
|
+
end
|
64
|
+
|
65
|
+
def metadata
|
66
|
+
render xml: self.class.sp_metadata.to_xml
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/config/routes.rb
CHANGED
@@ -2,12 +2,6 @@ module IntegrationPal
|
|
2
2
|
class InstallGenerator < Rails::Generators::Base
|
3
3
|
source_root File.expand_path('../templates', __FILE__)
|
4
4
|
|
5
|
-
desc "Add CAS config to application.rb"
|
6
|
-
def update_application_config
|
7
|
-
application "@cas_server_url = 'https://cas-sso.instructure.com/'"
|
8
|
-
application "config.rack_cas.server_url = @cas_server_url"
|
9
|
-
end
|
10
|
-
|
11
5
|
desc "Mount the engine"
|
12
6
|
def add_routes
|
13
7
|
route "mount IntegrationPal::Engine, at: IntegrationPal::Engine.mounted_path"
|
@@ -21,5 +15,16 @@ module IntegrationPal
|
|
21
15
|
end
|
22
16
|
end
|
23
17
|
|
18
|
+
desc "Add an initializer"
|
19
|
+
def add_initializer
|
20
|
+
initializer "integration_pal.rb" do
|
21
|
+
content = <<-'RUBY'
|
22
|
+
# SAML XML Metadata files. Looked for in config/saml. Automatically looks for an existing *.erb version as well.
|
23
|
+
# IntegrationPal.saml_idp_metadata = 'idp_metadata.xml'
|
24
|
+
# IntegrationPal.saml_sp_metadata = 'sp_metadata.xml'
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
24
29
|
end
|
25
30
|
end
|
data/lib/integration_pal.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: integration_pal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Tanner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.0.3
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rack-cas-rails
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.0.2
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 2.0.2
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: sentry-raven
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +108,20 @@ dependencies:
|
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: 4.3.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: saml2
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.2.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.2.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: pg
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,6 +211,7 @@ files:
|
|
211
211
|
- app/controllers/integration_pal/api_controller.rb
|
212
212
|
- app/controllers/integration_pal/application_controller.rb
|
213
213
|
- app/controllers/integration_pal/jobs_controller.rb
|
214
|
+
- app/controllers/integration_pal/saml_controller.rb
|
214
215
|
- app/controllers/integration_pal/tasks_controller.rb
|
215
216
|
- app/controllers/integration_pal/workers_controller.rb
|
216
217
|
- app/helpers/integration_pal/application_helper.rb
|
@@ -314,8 +315,6 @@ files:
|
|
314
315
|
- spec/dummy/config/secrets.yml
|
315
316
|
- spec/dummy/config/spring.rb
|
316
317
|
- spec/dummy/db/schema.rb
|
317
|
-
- spec/dummy/log/development.log
|
318
|
-
- spec/dummy/log/test.log
|
319
318
|
- spec/dummy/package.json
|
320
319
|
- spec/dummy/public/404.html
|
321
320
|
- spec/dummy/public/422.html
|
@@ -351,73 +350,71 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
351
350
|
version: '0'
|
352
351
|
requirements: []
|
353
352
|
rubyforge_project:
|
354
|
-
rubygems_version: 2.
|
353
|
+
rubygems_version: 2.5.2.1
|
355
354
|
signing_key:
|
356
355
|
specification_version: 4
|
357
356
|
summary: Mountable engine for SIS integrations
|
358
357
|
test_files:
|
359
|
-
- spec/
|
360
|
-
- spec/controllers/integration_pal/jobs_controller_spec.rb
|
361
|
-
- spec/controllers/integration_pal/workers_controller_spec.rb
|
362
|
-
- spec/dummy/app/assets/config/manifest.js
|
363
|
-
- spec/dummy/app/assets/javascripts/application.js
|
364
|
-
- spec/dummy/app/assets/javascripts/cable.js
|
365
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
366
|
-
- spec/dummy/app/channels/application_cable/channel.rb
|
367
|
-
- spec/dummy/app/channels/application_cable/connection.rb
|
368
|
-
- spec/dummy/app/controllers/application_controller.rb
|
369
|
-
- spec/dummy/app/helpers/application_helper.rb
|
370
|
-
- spec/dummy/app/jobs/application_job.rb
|
371
|
-
- spec/dummy/app/jobs/test_job.rb
|
358
|
+
- spec/spec_helper.rb
|
372
359
|
- spec/dummy/app/mailers/application_mailer.rb
|
373
360
|
- spec/dummy/app/models/application_record.rb
|
361
|
+
- spec/dummy/app/jobs/application_job.rb
|
362
|
+
- spec/dummy/app/jobs/test_job.rb
|
363
|
+
- spec/dummy/app/controllers/application_controller.rb
|
374
364
|
- spec/dummy/app/views/layouts/application.html.erb
|
375
365
|
- spec/dummy/app/views/layouts/mailer.html.erb
|
376
366
|
- spec/dummy/app/views/layouts/mailer.text.erb
|
377
|
-
- spec/dummy/
|
378
|
-
- spec/dummy/
|
367
|
+
- spec/dummy/app/assets/config/manifest.js
|
368
|
+
- spec/dummy/app/assets/javascripts/cable.js
|
369
|
+
- spec/dummy/app/assets/javascripts/application.js
|
370
|
+
- spec/dummy/app/assets/stylesheets/application.css
|
371
|
+
- spec/dummy/app/helpers/application_helper.rb
|
372
|
+
- spec/dummy/app/channels/application_cable/connection.rb
|
373
|
+
- spec/dummy/app/channels/application_cable/channel.rb
|
374
|
+
- spec/dummy/bin/update
|
379
375
|
- spec/dummy/bin/rake
|
380
376
|
- spec/dummy/bin/setup
|
381
|
-
- spec/dummy/bin/
|
377
|
+
- spec/dummy/bin/bundle
|
382
378
|
- spec/dummy/bin/yarn
|
383
|
-
- spec/dummy/
|
384
|
-
- spec/dummy/config/
|
379
|
+
- spec/dummy/bin/rails
|
380
|
+
- spec/dummy/config/secrets.yml
|
381
|
+
- spec/dummy/config/routes.rb
|
382
|
+
- spec/dummy/config/locales/en.yml
|
385
383
|
- spec/dummy/config/cable.yml
|
386
|
-
- spec/dummy/config/database.yml
|
387
|
-
- spec/dummy/config/environment.rb
|
388
|
-
- spec/dummy/config/environments/development.rb
|
389
384
|
- spec/dummy/config/environments/production.rb
|
385
|
+
- spec/dummy/config/environments/development.rb
|
390
386
|
- spec/dummy/config/environments/test.rb
|
387
|
+
- spec/dummy/config/spring.rb
|
388
|
+
- spec/dummy/config/environment.rb
|
389
|
+
- spec/dummy/config/application.rb
|
390
|
+
- spec/dummy/config/puma.rb
|
391
|
+
- spec/dummy/config/database.yml
|
392
|
+
- spec/dummy/config/boot.rb
|
391
393
|
- spec/dummy/config/initializers/application_controller_renderer.rb
|
392
|
-
- spec/dummy/config/initializers/assets.rb
|
393
394
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
394
|
-
- spec/dummy/config/initializers/cookies_serializer.rb
|
395
|
-
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
396
|
-
- spec/dummy/config/initializers/inflections.rb
|
397
395
|
- spec/dummy/config/initializers/mime_types.rb
|
396
|
+
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
398
397
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
399
|
-
- spec/dummy/config/
|
400
|
-
- spec/dummy/config/
|
401
|
-
- spec/dummy/config/
|
402
|
-
- spec/dummy/config/secrets.yml
|
403
|
-
- spec/dummy/config/spring.rb
|
398
|
+
- spec/dummy/config/initializers/assets.rb
|
399
|
+
- spec/dummy/config/initializers/cookies_serializer.rb
|
400
|
+
- spec/dummy/config/initializers/inflections.rb
|
404
401
|
- spec/dummy/config.ru
|
405
|
-
- spec/dummy/
|
406
|
-
- spec/dummy/
|
407
|
-
- spec/dummy/log/test.log
|
408
|
-
- spec/dummy/package.json
|
409
|
-
- spec/dummy/public/404.html
|
402
|
+
- spec/dummy/Rakefile
|
403
|
+
- spec/dummy/public/favicon.ico
|
410
404
|
- spec/dummy/public/422.html
|
405
|
+
- spec/dummy/public/apple-touch-icon.png
|
411
406
|
- spec/dummy/public/500.html
|
407
|
+
- spec/dummy/public/404.html
|
412
408
|
- spec/dummy/public/apple-touch-icon-precomposed.png
|
413
|
-
- spec/dummy/
|
414
|
-
- spec/dummy/
|
415
|
-
- spec/dummy/Rakefile
|
416
|
-
- spec/factories/integration_pal_jobs.rb
|
417
|
-
- spec/factories/integration_pal_tasks.rb
|
418
|
-
- spec/factories/integration_pal_workers.rb
|
419
|
-
- spec/models/integration_pal/job_spec.rb
|
409
|
+
- spec/dummy/package.json
|
410
|
+
- spec/dummy/db/schema.rb
|
420
411
|
- spec/models/integration_pal/task_spec.rb
|
412
|
+
- spec/models/integration_pal/job_spec.rb
|
421
413
|
- spec/models/integration_pal/worker_spec.rb
|
414
|
+
- spec/factories/integration_pal_tasks.rb
|
415
|
+
- spec/factories/integration_pal_jobs.rb
|
416
|
+
- spec/factories/integration_pal_workers.rb
|
417
|
+
- spec/controllers/integration_pal/workers_controller_spec.rb
|
418
|
+
- spec/controllers/integration_pal/jobs_controller_spec.rb
|
419
|
+
- spec/controllers/integration_pal/api/v1/jobs_controller_spec.rb
|
422
420
|
- spec/rails_helper.rb
|
423
|
-
- spec/spec_helper.rb
|