osso 0.0.5 → 0.0.10
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/.buildkite/pipeline.yml +3 -2
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/automerge.yml +19 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +49 -47
- data/Rakefile +3 -0
- data/bin/console +3 -0
- data/db/schema.rb +2 -2
- data/lib/osso.rb +0 -1
- data/lib/osso/db/migrate/20201125143501_add_salesforce_to_provider_service_enum.rb +28 -0
- data/lib/osso/graphql/types/identity_provider_service.rb +1 -0
- data/lib/osso/lib/app_config.rb +1 -1
- data/lib/osso/models/identity_provider.rb +1 -0
- data/lib/osso/routes/admin.rb +35 -7
- data/lib/osso/routes/oauth.rb +10 -4
- data/lib/osso/version.rb +1 -1
- data/lib/tasks/bootstrap.rake +9 -2
- data/osso-rb.gemspec +3 -3
- data/spec/models/identity_provider_spec.rb +1 -0
- data/spec/routes/admin_spec.rb +27 -9
- data/spec/routes/oauth_spec.rb +14 -0
- data/spec/support/views/hosted_login.erb +1 -0
- metadata +34 -15
- data/lib/osso/helpers/auth.rb +0 -94
- data/lib/osso/helpers/helpers.rb +0 -8
- data/spec/routes/app_spec.rb +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1ba94c32e61517dd429dd54e06ac24924ddb1245fff2c4dd1795d9e227972b4
|
|
4
|
+
data.tar.gz: bd239880638f0d8f344050c5fa92e110dc519c06e75321c28b3fa92e1860a2be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abb0e59b77e44230d47850e9e43d1a131a76694b6482706ce4d245f6832c823eeffebea468f75a4007e80ecf151271b5e9908e748e191b652c24c32984ff5c74
|
|
7
|
+
data.tar.gz: 12e250de2709aad8a60da53237a1489034d21f0caa05b084edabab93395266dd77060b0ad68a8d38956a9e8177315d3a35724a746aab04c438a3678194eeff4c
|
data/.buildkite/pipeline.yml
CHANGED
|
@@ -12,6 +12,7 @@ steps:
|
|
|
12
12
|
- coverage/*
|
|
13
13
|
|
|
14
14
|
- name: ":codeclimate:"
|
|
15
|
+
soft_fail: true
|
|
15
16
|
plugins:
|
|
16
17
|
- jobready/codeclimate-test-reporter#v2.0:
|
|
17
18
|
artifact: "coverage/.resultset.json"
|
|
@@ -19,8 +20,8 @@ steps:
|
|
|
19
20
|
prefix: '/var/lib/buildkite-agent/builds/enterprise-oss-bk-1/enterpriseoss/osso-rb/'
|
|
20
21
|
|
|
21
22
|
- block: ":rubygems: Publish :red_button:"
|
|
22
|
-
|
|
23
|
+
if: build.tag != null
|
|
23
24
|
|
|
24
25
|
- name: "Push :rubygems:"
|
|
25
26
|
commands: "./bin/publish"
|
|
26
|
-
|
|
27
|
+
if: build.tag != null
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: auto-merge
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
auto-approve:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v2
|
|
11
|
+
- uses: ahmadnassri/action-dependabot-auto-merge@v2
|
|
12
|
+
with:
|
|
13
|
+
target: minor
|
|
14
|
+
github-token: ${{ secrets.TOKEN }}
|
|
15
|
+
- uses: hmarr/auto-approve-action@v2.0.0
|
|
16
|
+
if: github.actor == 'dependabot[bot]'
|
|
17
|
+
with:
|
|
18
|
+
github-token: "${{ secrets.TOKEN }}"
|
|
19
|
+
|
data/Gemfile
CHANGED
|
@@ -10,10 +10,10 @@ group :test do
|
|
|
10
10
|
gem 'faker'
|
|
11
11
|
gem 'pg'
|
|
12
12
|
gem 'rack-test'
|
|
13
|
-
gem 'rspec', '~> 3.
|
|
13
|
+
gem 'rspec', '~> 3.10'
|
|
14
14
|
gem 'rubocop'
|
|
15
15
|
gem 'simplecov', '= 0.17', require: false
|
|
16
|
-
gem 'webmock', '~> 3.
|
|
16
|
+
gem 'webmock', '~> 3.11'
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
gemspec
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
osso (0.0.
|
|
4
|
+
osso (0.0.9)
|
|
5
5
|
activesupport (>= 6.0.3.2)
|
|
6
6
|
bcrypt (~> 3.1.13)
|
|
7
7
|
graphql
|
|
@@ -13,9 +13,9 @@ PATH
|
|
|
13
13
|
rack-contrib
|
|
14
14
|
rack-oauth2
|
|
15
15
|
rake
|
|
16
|
-
rodauth (
|
|
17
|
-
sequel (
|
|
18
|
-
sequel-activerecord_connection (
|
|
16
|
+
rodauth (>= 2.6, < 2.8)
|
|
17
|
+
sequel (>= 5.37, < 5.40)
|
|
18
|
+
sequel-activerecord_connection (>= 0.3, < 2.0)
|
|
19
19
|
sinatra
|
|
20
20
|
sinatra-activerecord
|
|
21
21
|
sinatra-contrib
|
|
@@ -23,20 +23,22 @@ PATH
|
|
|
23
23
|
GEM
|
|
24
24
|
remote: https://rubygems.org/
|
|
25
25
|
specs:
|
|
26
|
-
activemodel (6.0
|
|
27
|
-
activesupport (= 6.0
|
|
28
|
-
activerecord (6.0
|
|
29
|
-
activemodel (= 6.0
|
|
30
|
-
activesupport (= 6.0
|
|
31
|
-
activesupport (6.0
|
|
26
|
+
activemodel (6.1.0)
|
|
27
|
+
activesupport (= 6.1.0)
|
|
28
|
+
activerecord (6.1.0)
|
|
29
|
+
activemodel (= 6.1.0)
|
|
30
|
+
activesupport (= 6.1.0)
|
|
31
|
+
activesupport (6.1.0)
|
|
32
32
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
33
|
-
i18n (>=
|
|
34
|
-
minitest (
|
|
35
|
-
tzinfo (~>
|
|
36
|
-
zeitwerk (~> 2.
|
|
33
|
+
i18n (>= 1.6, < 2)
|
|
34
|
+
minitest (>= 5.1)
|
|
35
|
+
tzinfo (~> 2.0)
|
|
36
|
+
zeitwerk (~> 2.3)
|
|
37
37
|
addressable (2.7.0)
|
|
38
38
|
public_suffix (>= 2.0.2, < 5.0)
|
|
39
39
|
aes_key_wrap (1.1.0)
|
|
40
|
+
after_commit_everywhere (0.1.5)
|
|
41
|
+
activerecord (>= 4.2)
|
|
40
42
|
annotate (3.1.1)
|
|
41
43
|
activerecord (>= 3.2, < 7.0)
|
|
42
44
|
rake (>= 10.4, < 14.0)
|
|
@@ -55,7 +57,7 @@ GEM
|
|
|
55
57
|
docile (1.3.2)
|
|
56
58
|
factory_bot (6.1.0)
|
|
57
59
|
activesupport (>= 5.0.0)
|
|
58
|
-
faker (2.
|
|
60
|
+
faker (2.15.1)
|
|
59
61
|
i18n (>= 1.6, < 2)
|
|
60
62
|
graphql (1.11.6)
|
|
61
63
|
hashdiff (1.0.1)
|
|
@@ -64,7 +66,7 @@ GEM
|
|
|
64
66
|
i18n (1.8.5)
|
|
65
67
|
concurrent-ruby (~> 1.0)
|
|
66
68
|
json (2.3.1)
|
|
67
|
-
json-jwt (1.
|
|
69
|
+
json-jwt (1.12.0)
|
|
68
70
|
activesupport (>= 4.2)
|
|
69
71
|
aes_key_wrap
|
|
70
72
|
bindata
|
|
@@ -88,8 +90,8 @@ GEM
|
|
|
88
90
|
omniauth-saml (1.10.3)
|
|
89
91
|
omniauth (~> 1.3, >= 1.3.2)
|
|
90
92
|
ruby-saml (~> 1.9)
|
|
91
|
-
parallel (1.
|
|
92
|
-
parser (
|
|
93
|
+
parallel (1.20.1)
|
|
94
|
+
parser (3.0.0.0)
|
|
93
95
|
ast (~> 2.4.1)
|
|
94
96
|
pg (1.2.3)
|
|
95
97
|
pry (0.13.1)
|
|
@@ -97,7 +99,7 @@ GEM
|
|
|
97
99
|
method_source (~> 1.0)
|
|
98
100
|
public_suffix (4.0.6)
|
|
99
101
|
rack (2.2.3)
|
|
100
|
-
rack-contrib (2.
|
|
102
|
+
rack-contrib (2.3.0)
|
|
101
103
|
rack (~> 2.0)
|
|
102
104
|
rack-oauth2 (1.16.0)
|
|
103
105
|
activesupport
|
|
@@ -110,45 +112,46 @@ GEM
|
|
|
110
112
|
rack-test (1.1.0)
|
|
111
113
|
rack (>= 1.0, < 3)
|
|
112
114
|
rainbow (3.0.0)
|
|
113
|
-
rake (13.0.
|
|
114
|
-
regexp_parser (
|
|
115
|
+
rake (13.0.3)
|
|
116
|
+
regexp_parser (2.0.2)
|
|
115
117
|
rexml (3.2.4)
|
|
116
|
-
roda (3.
|
|
118
|
+
roda (3.39.0)
|
|
117
119
|
rack
|
|
118
|
-
rodauth (2.
|
|
120
|
+
rodauth (2.7.0)
|
|
119
121
|
roda (>= 2.6.0)
|
|
120
122
|
sequel (>= 4)
|
|
121
|
-
rspec (3.
|
|
122
|
-
rspec-core (~> 3.
|
|
123
|
-
rspec-expectations (~> 3.
|
|
124
|
-
rspec-mocks (~> 3.
|
|
125
|
-
rspec-core (3.
|
|
126
|
-
rspec-support (~> 3.
|
|
127
|
-
rspec-expectations (3.
|
|
123
|
+
rspec (3.10.0)
|
|
124
|
+
rspec-core (~> 3.10.0)
|
|
125
|
+
rspec-expectations (~> 3.10.0)
|
|
126
|
+
rspec-mocks (~> 3.10.0)
|
|
127
|
+
rspec-core (3.10.0)
|
|
128
|
+
rspec-support (~> 3.10.0)
|
|
129
|
+
rspec-expectations (3.10.0)
|
|
128
130
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
129
|
-
rspec-support (~> 3.
|
|
130
|
-
rspec-mocks (3.
|
|
131
|
+
rspec-support (~> 3.10.0)
|
|
132
|
+
rspec-mocks (3.10.0)
|
|
131
133
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
132
|
-
rspec-support (~> 3.
|
|
133
|
-
rspec-support (3.
|
|
134
|
-
rubocop (1.
|
|
134
|
+
rspec-support (~> 3.10.0)
|
|
135
|
+
rspec-support (3.10.0)
|
|
136
|
+
rubocop (1.7.0)
|
|
135
137
|
parallel (~> 1.10)
|
|
136
138
|
parser (>= 2.7.1.5)
|
|
137
139
|
rainbow (>= 2.2.2, < 4.0)
|
|
138
|
-
regexp_parser (>= 1.8)
|
|
140
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
139
141
|
rexml
|
|
140
|
-
rubocop-ast (>= 1.0.
|
|
142
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
|
141
143
|
ruby-progressbar (~> 1.7)
|
|
142
144
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
143
|
-
rubocop-ast (1.
|
|
145
|
+
rubocop-ast (1.3.0)
|
|
144
146
|
parser (>= 2.7.1.5)
|
|
145
147
|
ruby-progressbar (1.10.1)
|
|
146
148
|
ruby-saml (1.11.0)
|
|
147
149
|
nokogiri (>= 1.5.10)
|
|
148
150
|
ruby2_keywords (0.0.2)
|
|
149
|
-
sequel (5.
|
|
150
|
-
sequel-activerecord_connection (
|
|
151
|
+
sequel (5.39.0)
|
|
152
|
+
sequel-activerecord_connection (1.2.0)
|
|
151
153
|
activerecord (>= 4.2, < 7)
|
|
154
|
+
after_commit_everywhere (~> 0.1.5)
|
|
152
155
|
sequel (~> 5.16)
|
|
153
156
|
simplecov (0.17.0)
|
|
154
157
|
docile (~> 1.1)
|
|
@@ -169,16 +172,15 @@ GEM
|
|
|
169
172
|
rack-protection (= 2.1.0)
|
|
170
173
|
sinatra (= 2.1.0)
|
|
171
174
|
tilt (~> 2.0)
|
|
172
|
-
thread_safe (0.3.6)
|
|
173
175
|
tilt (2.0.10)
|
|
174
|
-
tzinfo (
|
|
175
|
-
|
|
176
|
+
tzinfo (2.0.3)
|
|
177
|
+
concurrent-ruby (~> 1.0)
|
|
176
178
|
unicode-display_width (1.7.0)
|
|
177
|
-
webmock (3.
|
|
179
|
+
webmock (3.11.0)
|
|
178
180
|
addressable (>= 2.3.6)
|
|
179
181
|
crack (>= 0.3.2)
|
|
180
182
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
181
|
-
zeitwerk (2.4.
|
|
183
|
+
zeitwerk (2.4.2)
|
|
182
184
|
|
|
183
185
|
PLATFORMS
|
|
184
186
|
ruby
|
|
@@ -193,10 +195,10 @@ DEPENDENCIES
|
|
|
193
195
|
pg
|
|
194
196
|
pry
|
|
195
197
|
rack-test
|
|
196
|
-
rspec (~> 3.
|
|
198
|
+
rspec (~> 3.10)
|
|
197
199
|
rubocop
|
|
198
200
|
simplecov (= 0.17)
|
|
199
|
-
webmock (~> 3.
|
|
201
|
+
webmock (~> 3.11)
|
|
200
202
|
|
|
201
203
|
BUNDLED WITH
|
|
202
204
|
2.1.4
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/db/schema.rb
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
12
12
|
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
|
13
|
+
ActiveRecord::Schema.define(version: 2020_11_25_143501) do
|
|
14
14
|
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
|
16
16
|
enable_extension "citext"
|
|
@@ -57,7 +57,7 @@ ActiveRecord::Schema.define(version: 2020_11_12_160120) do
|
|
|
57
57
|
t.citext "email", null: false
|
|
58
58
|
t.integer "status_id", default: 1, null: false
|
|
59
59
|
t.string "role", default: "admin", null: false
|
|
60
|
-
t.
|
|
60
|
+
t.string "oauth_client_id"
|
|
61
61
|
t.index ["email"], name: "index_accounts_on_email", unique: true, where: "(status_id = ANY (ARRAY[1, 2]))"
|
|
62
62
|
t.index ["oauth_client_id"], name: "index_accounts_on_oauth_client_id"
|
|
63
63
|
end
|
data/lib/osso.rb
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class AddSalesforceToProviderServiceEnum < ActiveRecord::Migration[6.0]
|
|
2
|
+
disable_ddl_transaction!
|
|
3
|
+
|
|
4
|
+
def up
|
|
5
|
+
execute <<-SQL
|
|
6
|
+
ALTER TYPE identity_provider_service ADD VALUE 'SALESFORCE';
|
|
7
|
+
SQL
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def down
|
|
11
|
+
execute <<~SQL
|
|
12
|
+
CREATE TYPE identity_provider_service_new AS ENUM ('AZURE', 'OKTA', 'ONELOGIN', 'GOOGLE', 'PING');
|
|
13
|
+
|
|
14
|
+
-- Remove values that won't be compatible with new definition
|
|
15
|
+
DELETE FROM identity_providers WHERE service = 'SALESFORCE';
|
|
16
|
+
|
|
17
|
+
-- Convert to new type, casting via text representation
|
|
18
|
+
ALTER TABLE identity_providers
|
|
19
|
+
ALTER COLUMN service TYPE identity_provider_service_new
|
|
20
|
+
USING (service::text::identity_provider_service_new);
|
|
21
|
+
|
|
22
|
+
-- and swap the types
|
|
23
|
+
DROP TYPE identity_provider_service;
|
|
24
|
+
|
|
25
|
+
ALTER TYPE identity_provider_service_new RENAME TO identity_provider_service;
|
|
26
|
+
SQL
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -9,6 +9,7 @@ module Osso
|
|
|
9
9
|
value('OKTA', 'Okta Identity Provider', value: 'OKTA')
|
|
10
10
|
value('ONELOGIN', 'OneLogin Identity Provider', value: 'ONELOGIN')
|
|
11
11
|
value('PING', 'PingID Identity Provider', value: 'PING')
|
|
12
|
+
value('SALESFORCE', 'Salesforce Identity Provider', value: 'SALESFORCE')
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
end
|
data/lib/osso/lib/app_config.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Osso
|
|
|
7
7
|
def self.included(klass)
|
|
8
8
|
klass.class_eval do
|
|
9
9
|
use Rack::JSONBodyParser
|
|
10
|
-
use Rack::Session::Cookie, secret: ENV
|
|
10
|
+
use Rack::Session::Cookie, secret: ENV.fetch('SESSION_SECRET')
|
|
11
11
|
|
|
12
12
|
error ActiveRecord::RecordNotFound do
|
|
13
13
|
status 404
|
data/lib/osso/routes/admin.rb
CHANGED
|
@@ -8,18 +8,43 @@ DEFAULT_VIEWS_DIR = File.join(File.expand_path(Bundler.root), 'views/rodauth')
|
|
|
8
8
|
module Osso
|
|
9
9
|
class Admin < Roda
|
|
10
10
|
DB = Sequel.postgres(extensions: :activerecord_connection)
|
|
11
|
-
use Rack::Session::Cookie, secret: ENV
|
|
12
|
-
|
|
11
|
+
use Rack::Session::Cookie, secret: ENV.fetch('SESSION_SECRET')
|
|
12
|
+
|
|
13
|
+
plugin :json
|
|
13
14
|
plugin :middleware
|
|
14
15
|
plugin :render, engine: 'erb', views: ENV['RODAUTH_VIEWS'] || DEFAULT_VIEWS_DIR
|
|
15
16
|
plugin :route_csrf
|
|
16
17
|
|
|
17
18
|
plugin :rodauth do
|
|
18
|
-
enable :login, :verify_account
|
|
19
|
+
enable :login, :verify_account, :jwt
|
|
20
|
+
|
|
21
|
+
base_uri = URI.parse(ENV.fetch('BASE_URL'))
|
|
22
|
+
base_url base_uri
|
|
23
|
+
domain base_uri.host
|
|
24
|
+
|
|
25
|
+
jwt_secret ENV.fetch('SESSION_SECRET')
|
|
26
|
+
only_json? false
|
|
27
|
+
|
|
28
|
+
email_from { "Osso <no-reply@#{domain}>" }
|
|
19
29
|
verify_account_set_password? true
|
|
20
|
-
already_logged_in { redirect login_redirect }
|
|
21
30
|
use_database_authentication_functions? false
|
|
22
31
|
|
|
32
|
+
verify_account_view do
|
|
33
|
+
render :admin
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
login_view do
|
|
37
|
+
render :admin
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
verify_account_email_subject do
|
|
41
|
+
DB[:accounts].one? ? 'Your Osso instance is ready' : 'You\'ve been invited to start using Osso'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
verify_account_email_body do
|
|
45
|
+
DB[:accounts].one? ? render('verify-first-account-email') : render('verify-account-email')
|
|
46
|
+
end
|
|
47
|
+
|
|
23
48
|
before_create_account_route do
|
|
24
49
|
request.halt unless DB[:accounts].empty?
|
|
25
50
|
end
|
|
@@ -31,13 +56,16 @@ module Osso
|
|
|
31
56
|
r.rodauth
|
|
32
57
|
|
|
33
58
|
def current_account
|
|
34
|
-
Osso::Models::Account.find(
|
|
35
|
-
|
|
59
|
+
Osso::Models::Account.find(
|
|
60
|
+
rodauth.
|
|
61
|
+
session.
|
|
62
|
+
to_hash.
|
|
63
|
+
stringify_keys['account_id']
|
|
64
|
+
).context.
|
|
36
65
|
merge({ rodauth: rodauth })
|
|
37
66
|
end
|
|
38
67
|
|
|
39
68
|
r.on 'admin' do
|
|
40
|
-
rodauth.require_authentication
|
|
41
69
|
erb :admin, layout: false
|
|
42
70
|
end
|
|
43
71
|
|
data/lib/osso/routes/oauth.rb
CHANGED
|
@@ -16,13 +16,14 @@ module Osso
|
|
|
16
16
|
# Once they complete IdP login, they will be returned to the
|
|
17
17
|
# redirect_uri with an authorization code parameter.
|
|
18
18
|
get '/authorize' do
|
|
19
|
-
identity_providers = find_providers
|
|
20
|
-
|
|
21
19
|
validate_oauth_request(env)
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
return erb :hosted_login if render_hosted_login?
|
|
22
|
+
|
|
23
|
+
@providers = find_providers
|
|
24
|
+
|
|
25
|
+
redirect "/auth/saml/#{@providers.first.id}" if @providers.one?
|
|
24
26
|
|
|
25
|
-
@providers = identity_providers.not_pending
|
|
26
27
|
return erb :multiple_providers if @providers.count > 1
|
|
27
28
|
|
|
28
29
|
raise Osso::Error::MissingConfiguredIdentityProvider.new(domain: params[:domain])
|
|
@@ -61,6 +62,10 @@ module Osso
|
|
|
61
62
|
|
|
62
63
|
private
|
|
63
64
|
|
|
65
|
+
def render_hosted_login?
|
|
66
|
+
[params[:email], params[:domain]].all?(&:nil?)
|
|
67
|
+
end
|
|
68
|
+
|
|
64
69
|
def find_providers
|
|
65
70
|
if params[:email]
|
|
66
71
|
user = Osso::Models::User.
|
|
@@ -71,6 +76,7 @@ module Osso
|
|
|
71
76
|
|
|
72
77
|
Osso::Models::IdentityProvider.
|
|
73
78
|
joins(:oauth_client).
|
|
79
|
+
not_pending.
|
|
74
80
|
where(
|
|
75
81
|
domain: domain_from_params,
|
|
76
82
|
oauth_clients: { identifier: params[:client_id] },
|
data/lib/osso/version.rb
CHANGED
data/lib/tasks/bootstrap.rake
CHANGED
|
@@ -18,13 +18,20 @@ namespace :osso do
|
|
|
18
18
|
admin_email = ENV['ADMIN_EMAIL']
|
|
19
19
|
|
|
20
20
|
if admin_email
|
|
21
|
-
admin = Osso::Models::Account.create
|
|
21
|
+
admin = Osso::Models::Account.create(
|
|
22
22
|
email: admin_email,
|
|
23
23
|
status_id: 1,
|
|
24
24
|
role: 'admin',
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
base_uri = URI.parse(ENV['BASE_URL'])
|
|
28
|
+
|
|
29
|
+
rodauth = Osso::Admin.rodauth.new(Osso::Admin.new({
|
|
30
|
+
'HTTP_HOST' => base_uri.host,
|
|
31
|
+
'SERVER_NAME' => base_uri.to_s,
|
|
32
|
+
'rack.url_scheme' => base_uri.scheme
|
|
33
|
+
}))
|
|
34
|
+
|
|
28
35
|
account = rodauth.account_from_login(admin_email)
|
|
29
36
|
rodauth.setup_account_verification
|
|
30
37
|
end
|
data/osso-rb.gemspec
CHANGED
|
@@ -26,9 +26,9 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.add_runtime_dependency 'rack-contrib'
|
|
27
27
|
spec.add_runtime_dependency 'rack-oauth2'
|
|
28
28
|
spec.add_runtime_dependency 'rake'
|
|
29
|
-
spec.add_runtime_dependency 'rodauth', '
|
|
30
|
-
spec.add_runtime_dependency 'sequel', '
|
|
31
|
-
spec.add_runtime_dependency 'sequel-activerecord_connection', '
|
|
29
|
+
spec.add_runtime_dependency 'rodauth', '>= 2.6', '< 2.8'
|
|
30
|
+
spec.add_runtime_dependency 'sequel', '>= 5.37', '< 5.40'
|
|
31
|
+
spec.add_runtime_dependency 'sequel-activerecord_connection', '>= 0.3', '< 2.0'
|
|
32
32
|
spec.add_runtime_dependency 'sinatra'
|
|
33
33
|
spec.add_runtime_dependency 'sinatra-activerecord'
|
|
34
34
|
spec.add_runtime_dependency 'sinatra-contrib'
|
data/spec/routes/admin_spec.rb
CHANGED
|
@@ -4,23 +4,41 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Osso::Admin do
|
|
6
6
|
describe 'get /admin' do
|
|
7
|
-
it '
|
|
7
|
+
it 'renders the admin layout' do
|
|
8
8
|
get('/admin')
|
|
9
9
|
|
|
10
|
-
expect(last_response).to
|
|
11
|
-
follow_redirect!
|
|
12
|
-
expect(last_request.url).to match('/login')
|
|
10
|
+
expect(last_response).to be_ok
|
|
13
11
|
end
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
account = create(:verified_account, password: password)
|
|
14
|
+
describe 'post /graphql' do
|
|
15
|
+
let(:account) { create(:account) }
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
it 'runs a GraphQL query with a valid jwt' do
|
|
18
|
+
allow_any_instance_of(described_class.rodauth).to receive(:logged_in?).and_return(true)
|
|
19
|
+
allow(Osso::Models::Account).to receive(:find).and_return(account)
|
|
20
|
+
allow(Osso::GraphQL::Schema).to receive(:execute).and_return({graphql: true})
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
header 'Content-Type', 'application/json'
|
|
23
|
+
post("/graphql")
|
|
22
24
|
|
|
23
25
|
expect(last_response).to be_ok
|
|
26
|
+
expect(last_json_response).to eq({graphql: true})
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'returns a 400 for an invalid jwt' do
|
|
30
|
+
header 'Content-Type', 'application/json'
|
|
31
|
+
header 'Authorization', 'Bearer bad-token'
|
|
32
|
+
post("/graphql")
|
|
33
|
+
|
|
34
|
+
expect(last_response.status).to eq 400
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'returns a 401 without a jwt' do
|
|
38
|
+
header 'Content-Type', 'application/json'
|
|
39
|
+
post("/graphql")
|
|
40
|
+
|
|
41
|
+
expect(last_response.status).to eq 401
|
|
24
42
|
end
|
|
25
43
|
end
|
|
26
44
|
end
|
data/spec/routes/oauth_spec.rb
CHANGED
|
@@ -27,6 +27,20 @@ describe Osso::Oauth do
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
describe 'for a request without email or domain' do
|
|
31
|
+
it 'redirects to /auth/saml/:provider_id' do
|
|
32
|
+
get(
|
|
33
|
+
'/oauth/authorize',
|
|
34
|
+
client_id: client.identifier,
|
|
35
|
+
response_type: 'code',
|
|
36
|
+
redirect_uri: client.redirect_uri_values.sample,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(last_response).to be_ok
|
|
40
|
+
expect(last_response.body).to eq('HOSTED LOGIN')
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
30
44
|
describe 'for an enterprise domain with one SAML provider' do
|
|
31
45
|
it 'redirects to /auth/saml/:provider_id' do
|
|
32
46
|
enterprise = create(:enterprise_with_okta, oauth_client: client)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
HOSTED LOGIN
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: osso
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Bauch
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-12-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -168,44 +168,62 @@ dependencies:
|
|
|
168
168
|
name: rodauth
|
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
|
170
170
|
requirements:
|
|
171
|
-
- - "
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '2.6'
|
|
174
|
+
- - "<"
|
|
172
175
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 2.
|
|
176
|
+
version: '2.8'
|
|
174
177
|
type: :runtime
|
|
175
178
|
prerelease: false
|
|
176
179
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
180
|
requirements:
|
|
178
|
-
- - "
|
|
181
|
+
- - ">="
|
|
179
182
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: 2.
|
|
183
|
+
version: '2.6'
|
|
184
|
+
- - "<"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '2.8'
|
|
181
187
|
- !ruby/object:Gem::Dependency
|
|
182
188
|
name: sequel
|
|
183
189
|
requirement: !ruby/object:Gem::Requirement
|
|
184
190
|
requirements:
|
|
185
|
-
- - "
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '5.37'
|
|
194
|
+
- - "<"
|
|
186
195
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: 5.
|
|
196
|
+
version: '5.40'
|
|
188
197
|
type: :runtime
|
|
189
198
|
prerelease: false
|
|
190
199
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
200
|
requirements:
|
|
192
|
-
- - "
|
|
201
|
+
- - ">="
|
|
202
|
+
- !ruby/object:Gem::Version
|
|
203
|
+
version: '5.37'
|
|
204
|
+
- - "<"
|
|
193
205
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 5.
|
|
206
|
+
version: '5.40'
|
|
195
207
|
- !ruby/object:Gem::Dependency
|
|
196
208
|
name: sequel-activerecord_connection
|
|
197
209
|
requirement: !ruby/object:Gem::Requirement
|
|
198
210
|
requirements:
|
|
199
|
-
- - "
|
|
211
|
+
- - ">="
|
|
200
212
|
- !ruby/object:Gem::Version
|
|
201
213
|
version: '0.3'
|
|
214
|
+
- - "<"
|
|
215
|
+
- !ruby/object:Gem::Version
|
|
216
|
+
version: '2.0'
|
|
202
217
|
type: :runtime
|
|
203
218
|
prerelease: false
|
|
204
219
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
220
|
requirements:
|
|
206
|
-
- - "
|
|
221
|
+
- - ">="
|
|
207
222
|
- !ruby/object:Gem::Version
|
|
208
223
|
version: '0.3'
|
|
224
|
+
- - "<"
|
|
225
|
+
- !ruby/object:Gem::Version
|
|
226
|
+
version: '2.0'
|
|
209
227
|
- !ruby/object:Gem::Dependency
|
|
210
228
|
name: sinatra
|
|
211
229
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -305,6 +323,8 @@ files:
|
|
|
305
323
|
- ".buildkite/hooks/pre-command"
|
|
306
324
|
- ".buildkite/pipeline.yml"
|
|
307
325
|
- ".buildkite/template.yml"
|
|
326
|
+
- ".github/dependabot.yml"
|
|
327
|
+
- ".github/workflows/automerge.yml"
|
|
308
328
|
- ".gitignore"
|
|
309
329
|
- ".rspec"
|
|
310
330
|
- ".rubocop.yml"
|
|
@@ -350,6 +370,7 @@ files:
|
|
|
350
370
|
- lib/osso/db/migrate/20201109160851_add_sso_issuer_to_identity_providers.rb
|
|
351
371
|
- lib/osso/db/migrate/20201110190754_remove_oauth_client_id_from_enterprise_accounts.rb
|
|
352
372
|
- lib/osso/db/migrate/20201112160120_add_ping_to_identity_provider_service_enum.rb
|
|
373
|
+
- lib/osso/db/migrate/20201125143501_add_salesforce_to_provider_service_enum.rb
|
|
353
374
|
- lib/osso/error/account_configuration_error.rb
|
|
354
375
|
- lib/osso/error/error.rb
|
|
355
376
|
- lib/osso/error/missing_saml_attribute_error.rb
|
|
@@ -392,8 +413,6 @@ files:
|
|
|
392
413
|
- lib/osso/graphql/types/oauth_client.rb
|
|
393
414
|
- lib/osso/graphql/types/redirect_uri.rb
|
|
394
415
|
- lib/osso/graphql/types/redirect_uri_input.rb
|
|
395
|
-
- lib/osso/helpers/auth.rb
|
|
396
|
-
- lib/osso/helpers/helpers.rb
|
|
397
416
|
- lib/osso/lib/app_config.rb
|
|
398
417
|
- lib/osso/lib/oauth2_token.rb
|
|
399
418
|
- lib/osso/lib/route_map.rb
|
|
@@ -442,7 +461,6 @@ files:
|
|
|
442
461
|
- spec/models/enterprise_account_spec.rb
|
|
443
462
|
- spec/models/identity_provider_spec.rb
|
|
444
463
|
- spec/routes/admin_spec.rb
|
|
445
|
-
- spec/routes/app_spec.rb
|
|
446
464
|
- spec/routes/auth_spec.rb
|
|
447
465
|
- spec/routes/oauth_spec.rb
|
|
448
466
|
- spec/spec_helper.rb
|
|
@@ -450,6 +468,7 @@ files:
|
|
|
450
468
|
- spec/support/spec_app.rb
|
|
451
469
|
- spec/support/views/admin.erb
|
|
452
470
|
- spec/support/views/error.erb
|
|
471
|
+
- spec/support/views/hosted_login.erb
|
|
453
472
|
- spec/support/views/layout.erb
|
|
454
473
|
- spec/support/views/multiple_providers.erb
|
|
455
474
|
homepage: https://github.com/enterprise-oss/osso-rb
|
data/lib/osso/helpers/auth.rb
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Osso
|
|
4
|
-
module Helpers
|
|
5
|
-
module Auth
|
|
6
|
-
END_USER_SCOPE = 'end-user'
|
|
7
|
-
INTERNAL_SCOPE = 'internal'
|
|
8
|
-
ADMIN_SCOPE = 'admin'
|
|
9
|
-
|
|
10
|
-
attr_accessor :current_user
|
|
11
|
-
|
|
12
|
-
def token_protected!
|
|
13
|
-
decode(token)
|
|
14
|
-
rescue JWT::DecodeError
|
|
15
|
-
halt 401
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def enterprise_protected!(domain = nil)
|
|
19
|
-
return if admin_authorized?
|
|
20
|
-
return if internal_authorized?
|
|
21
|
-
return if enterprise_authorized?(domain)
|
|
22
|
-
|
|
23
|
-
halt 401 if request.post?
|
|
24
|
-
|
|
25
|
-
redirect ENV['JWT_URL']
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def internal_protected!
|
|
29
|
-
return if admin_authorized?
|
|
30
|
-
return if internal_authorized?
|
|
31
|
-
|
|
32
|
-
redirect ENV['JWT_URL']
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def admin_protected!
|
|
36
|
-
return true if admin_authorized?
|
|
37
|
-
|
|
38
|
-
redirect ENV['JWT_URL']
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
def enterprise_authorized?(domain)
|
|
44
|
-
decode(token)
|
|
45
|
-
|
|
46
|
-
@current_user[:scope] == END_USER_SCOPE &&
|
|
47
|
-
@current_user[:email].split('@')[1] == domain
|
|
48
|
-
rescue JWT::DecodeError
|
|
49
|
-
false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def internal_authorized?
|
|
53
|
-
decode(token)
|
|
54
|
-
|
|
55
|
-
@current_user[:scope] == INTERNAL_SCOPE
|
|
56
|
-
rescue JWT::DecodeError
|
|
57
|
-
false
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def admin_authorized?
|
|
61
|
-
decode(token)
|
|
62
|
-
|
|
63
|
-
@current_user[:scope] == ADMIN_SCOPE
|
|
64
|
-
rescue JWT::DecodeError
|
|
65
|
-
false
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def token
|
|
69
|
-
session['admin_token'] || request.env['HTTP_AUTHORIZATION'] || request.params['admin_token']
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def chomp_token
|
|
73
|
-
return unless request['admin_token'].present?
|
|
74
|
-
|
|
75
|
-
session['admin_token'] = request['admin_token']
|
|
76
|
-
|
|
77
|
-
return if request.post?
|
|
78
|
-
|
|
79
|
-
redirect request.path
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def decode(token)
|
|
83
|
-
payload, _args = JWT.decode(
|
|
84
|
-
token,
|
|
85
|
-
ENV['JWT_HMAC_SECRET'],
|
|
86
|
-
true,
|
|
87
|
-
{ algorithm: 'HS256' },
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
@current_user = payload.symbolize_keys
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
data/lib/osso/helpers/helpers.rb
DELETED