osso 0.0.3.14 → 0.0.3.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.yml +17 -1
  3. data/.rubocop.yml +1 -0
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +10 -2
  6. data/README.md +3 -2
  7. data/bin/publish +18 -0
  8. data/db/schema.rb +9 -1
  9. data/lib/osso/db/migrate/20200826201852_create_app_config.rb +11 -0
  10. data/lib/osso/graphql/mutation.rb +7 -0
  11. data/lib/osso/graphql/mutations.rb +2 -0
  12. data/lib/osso/graphql/mutations/base_mutation.rb +18 -5
  13. data/lib/osso/graphql/mutations/configure_identity_provider.rb +8 -10
  14. data/lib/osso/graphql/mutations/create_enterprise_account.rb +7 -0
  15. data/lib/osso/graphql/mutations/create_identity_provider.rb +14 -5
  16. data/lib/osso/graphql/mutations/create_oauth_client.rb +1 -3
  17. data/lib/osso/graphql/mutations/delete_enterprise_account.rb +9 -11
  18. data/lib/osso/graphql/mutations/delete_oauth_client.rb +1 -3
  19. data/lib/osso/graphql/mutations/regenerate_oauth_credentials.rb +1 -3
  20. data/lib/osso/graphql/mutations/set_redirect_uris.rb +2 -4
  21. data/lib/osso/graphql/mutations/update_app_config.rb +30 -0
  22. data/lib/osso/graphql/query.rb +14 -0
  23. data/lib/osso/graphql/resolvers.rb +1 -0
  24. data/lib/osso/graphql/resolvers/base_resolver.rb +21 -0
  25. data/lib/osso/graphql/resolvers/enterprise_account.rb +1 -11
  26. data/lib/osso/graphql/resolvers/enterprise_accounts.rb +2 -2
  27. data/lib/osso/graphql/resolvers/oauth_clients.rb +2 -2
  28. data/lib/osso/graphql/types.rb +2 -1
  29. data/lib/osso/graphql/types/admin_user.rb +22 -0
  30. data/lib/osso/graphql/types/app_config.rb +22 -0
  31. data/lib/osso/graphql/types/base_object.rb +22 -0
  32. data/lib/osso/graphql/types/enterprise_account.rb +0 -5
  33. data/lib/osso/graphql/types/identity_provider.rb +0 -6
  34. data/lib/osso/graphql/types/oauth_client.rb +2 -4
  35. data/lib/osso/graphql/types/redirect_uri.rb +2 -4
  36. data/lib/osso/helpers/auth.rb +40 -18
  37. data/lib/osso/lib/route_map.rb +2 -2
  38. data/lib/osso/models/app_config.rb +33 -0
  39. data/lib/osso/models/identity_provider.rb +6 -12
  40. data/lib/osso/models/models.rb +1 -0
  41. data/lib/osso/models/oauth_client.rb +1 -0
  42. data/lib/osso/models/redirect_uri.rb +0 -11
  43. data/lib/osso/routes/admin.rb +2 -2
  44. data/lib/osso/routes/auth.rb +29 -12
  45. data/lib/osso/routes/oauth.rb +25 -18
  46. data/lib/osso/version.rb +1 -1
  47. data/lib/tasks/bootstrap.rake +2 -0
  48. data/spec/graphql/mutations/configure_identity_provider_spec.rb +17 -4
  49. data/spec/graphql/mutations/create_enterprise_account_spec.rb +53 -4
  50. data/spec/graphql/mutations/create_identity_provider_spec.rb +18 -6
  51. data/spec/graphql/mutations/create_oauth_client_spec.rb +10 -3
  52. data/spec/graphql/mutations/delete_enterprise_account_spec.rb +18 -4
  53. data/spec/graphql/mutations/delete_oauth_client_spec.rb +8 -4
  54. data/spec/graphql/query/enterprise_account_spec.rb +21 -6
  55. data/spec/graphql/query/enterprise_accounts_spec.rb +4 -2
  56. data/spec/graphql/query/identity_provider_spec.rb +16 -6
  57. data/spec/graphql/query/oauth_clients_spec.rb +10 -7
  58. data/spec/helpers/auth_spec.rb +97 -0
  59. data/spec/models/identity_provider_spec.rb +12 -0
  60. data/spec/routes/auth_spec.rb +18 -0
  61. data/spec/routes/oauth_spec.rb +5 -2
  62. data/spec/spec_helper.rb +3 -0
  63. data/spec/support/views/error.erb +0 -0
  64. metadata +15 -6
  65. data/lib/osso/graphql/types/user.rb +0 -17
@@ -29,21 +29,25 @@ describe Osso::GraphQL::Schema do
29
29
  described_class.execute(
30
30
  mutation,
31
31
  variables: variables,
32
- context: { scope: current_scope },
32
+ context: current_context,
33
33
  )
34
34
  end
35
35
 
36
36
  describe 'for an admin user' do
37
- let(:current_scope) { :admin }
37
+ let(:current_context) do
38
+ { scope: 'admin' }
39
+ end
38
40
  it 'deletes the OauthClient' do
39
41
  expect { subject }.to change { Osso::Models::OauthClient.count }.by(-1)
40
42
  end
41
43
  end
42
44
 
43
45
  describe 'for an email scoped user' do
44
- let(:current_scope) { 'foo.com' }
46
+ let(:current_context) do
47
+ { scope: 'end-user', email: 'user@foo.com' }
48
+ end
45
49
 
46
- it 'does not create an OauthClient Account' do
50
+ it 'does not deletes the OauthClient' do
47
51
  expect { subject }.to_not(change { Osso::Models::OauthClient.count })
48
52
  end
49
53
  end
@@ -37,12 +37,17 @@ describe Osso::GraphQL::Schema do
37
37
  described_class.execute(
38
38
  query,
39
39
  variables: variables,
40
- context: { scope: current_scope },
40
+ context: current_context,
41
41
  )
42
42
  end
43
43
 
44
44
  describe 'for an admin user' do
45
- let(:current_scope) { :admin }
45
+ let(:current_context) do
46
+ {
47
+ scope: 'admin',
48
+ }
49
+ end
50
+
46
51
  it 'returns Enterprise Account for domain' do
47
52
  expect(subject['errors']).to be_nil
48
53
  expect(subject.dig('data', 'enterpriseAccount', 'domain')).to eq(domain)
@@ -50,7 +55,12 @@ describe Osso::GraphQL::Schema do
50
55
  end
51
56
 
52
57
  describe 'for an email scoped user' do
53
- let(:current_scope) { domain }
58
+ let(:current_context) do
59
+ {
60
+ scope: 'end-user',
61
+ email: "user@#{domain}",
62
+ }
63
+ end
54
64
  it 'returns Enterprise Account for domain' do
55
65
  expect(subject['errors']).to be_nil
56
66
  expect(subject.dig('data', 'enterpriseAccount', 'domain')).to eq(domain)
@@ -58,9 +68,14 @@ describe Osso::GraphQL::Schema do
58
68
  end
59
69
 
60
70
  describe 'for the wrong email scoped user' do
61
- let(:current_scope) { 'bar.com' }
62
- it 'returns Enterprise Account for domain' do
63
- expect(subject['errors']).to be_nil
71
+ let(:current_context) do
72
+ {
73
+ scope: 'end-user',
74
+ email: 'foo@bar.com',
75
+ }
76
+ end
77
+ it 'does not return Enterprise Account for domain' do
78
+ expect(subject['errors']).to_not be_nil
64
79
  expect(subject.dig('data', 'enterpriseAccount')).to be_nil
65
80
  end
66
81
  end
@@ -5,7 +5,9 @@ require 'spec_helper'
5
5
  describe Osso::GraphQL::Schema do
6
6
  describe 'EnterpriseAccounts' do
7
7
  describe 'for an admin user' do
8
- let(:current_scope) { :admin }
8
+ let(:current_context) do
9
+ { scope: 'admin' }
10
+ end
9
11
 
10
12
  it 'returns paginated Enterprise Accounts' do
11
13
  %w[A B C].map do |name|
@@ -44,7 +46,7 @@ describe Osso::GraphQL::Schema do
44
46
  response = described_class.execute(
45
47
  query,
46
48
  variables: { first: 2, sortOrder: 'descending', sortColumn: 'name' },
47
- context: { scope: current_scope },
49
+ context: current_context,
48
50
  )
49
51
 
50
52
  expect(response['errors']).to be_nil
@@ -32,12 +32,14 @@ describe Osso::GraphQL::Schema do
32
32
  described_class.execute(
33
33
  query,
34
34
  variables: variables,
35
- context: { scope: current_scope },
35
+ context: current_context,
36
36
  )
37
37
  end
38
38
 
39
39
  describe 'for an admin user' do
40
- let(:current_scope) { :admin }
40
+ let(:current_context) do
41
+ { scope: 'admin' }
42
+ end
41
43
  it 'returns Identity Provider for id' do
42
44
  expect(subject['errors']).to be_nil
43
45
  expect(subject.dig('data', 'identityProvider', 'id')).to eq(id)
@@ -45,8 +47,12 @@ describe Osso::GraphQL::Schema do
45
47
  end
46
48
 
47
49
  describe 'for an email scoped user' do
48
- let(:current_scope) { domain }
49
-
50
+ let(:current_context) do
51
+ {
52
+ scope: 'end-user',
53
+ email: "user@#{domain}",
54
+ }
55
+ end
50
56
  it 'returns Enterprise Account for domain' do
51
57
  expect(subject['errors']).to be_nil
52
58
  expect(subject.dig('data', 'identityProvider', 'domain')).to eq(domain)
@@ -54,8 +60,12 @@ describe Osso::GraphQL::Schema do
54
60
  end
55
61
 
56
62
  describe 'for the wrong email scoped user' do
57
- let(:current_scope) { 'bar.com' }
58
-
63
+ let(:current_context) do
64
+ {
65
+ scope: 'end-user',
66
+ email: 'user@bar.com',
67
+ }
68
+ end
59
69
  it 'returns Enterprise Account for domain' do
60
70
  expect(subject['errors']).to_not be_empty
61
71
  expect(subject.dig('data', 'enterpriseAccount')).to be_nil
@@ -25,12 +25,14 @@ describe Osso::GraphQL::Schema do
25
25
  described_class.execute(
26
26
  query,
27
27
  variables: nil,
28
- context: { scope: current_scope },
28
+ context: current_context,
29
29
  )
30
30
  end
31
31
 
32
32
  describe 'for an admin user' do
33
- let(:current_scope) { :admin }
33
+ let(:current_context) do
34
+ { scope: 'admin' }
35
+ end
34
36
 
35
37
  it 'returns Oauth Clients' do
36
38
  expect(subject['errors']).to be_nil
@@ -38,11 +40,12 @@ describe Osso::GraphQL::Schema do
38
40
  end
39
41
  end
40
42
 
41
- describe 'for an email scoped user' do
42
- let(:current_scope) { 'foo.com' }
43
-
44
- it 'returns Oauth Clients' do
45
- expect(subject['errors']).to be_nil
43
+ describe 'for an internal scoped user' do
44
+ let(:current_context) do
45
+ { scope: 'internal' }
46
+ end
47
+ it 'does not return Oauth Clients' do
48
+ expect(subject['errors']).to_not be_nil
46
49
  expect(subject.dig('data', 'oauthClients')).to be_nil
47
50
  end
48
51
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::Helpers::Auth do
6
+ before do
7
+ ENV['JWT_HMAC_SECRET'] = 'super-secret'
8
+ end
9
+
10
+ subject(:app) do
11
+ Class.new { include Osso::Helpers::Auth }
12
+ end
13
+
14
+ describe 'with the token as a header' do
15
+ before do
16
+ allow_any_instance_of(subject).to receive(:request) do
17
+ double('Request', env: { 'admin_token' => token }, post?: false)
18
+ end
19
+
20
+ allow_any_instance_of(subject).to receive(:redirect) do
21
+ false
22
+ end
23
+ end
24
+
25
+ describe 'with an admin token' do
26
+ let(:token) { encode({ scope: 'admin' }) }
27
+
28
+ it 'allows #token_protected! methods' do
29
+ expect(subject.new.token_protected!).to_not be(false)
30
+ end
31
+
32
+ it 'allows #enterprise_protected! methods' do
33
+ expect(subject.new.enterprise_protected!).to_not be(false)
34
+ end
35
+
36
+ it 'allows #internal_protected! methods' do
37
+ expect(subject.new.internal_protected!).to_not be(false)
38
+ end
39
+
40
+ it 'allows #admin_protected! methods' do
41
+ expect(subject.new.admin_protected!).to_not be(false)
42
+ end
43
+ end
44
+
45
+ describe 'with an internal token' do
46
+ let(:token) { encode({ scope: 'internal' }) }
47
+
48
+ it 'allows #token_protected! methods' do
49
+ expect(subject.new.token_protected!).to_not be(false)
50
+ end
51
+
52
+ it 'allows #enterprise_protected! methods' do
53
+ expect(subject.new.enterprise_protected!).to_not be(false)
54
+ end
55
+
56
+ it 'allows #internal_protected! methods' do
57
+ expect(subject.new.internal_protected!).to_not be(false)
58
+ end
59
+
60
+ it 'allows #admin_protected! methods' do
61
+ expect(subject.new.admin_protected!).to be(false)
62
+ end
63
+ end
64
+
65
+ describe 'with an end-user token' do
66
+ let(:token) { encode({ scope: 'end-user', email: 'user@example.com' }) }
67
+
68
+ it 'allows #token_protected! methods' do
69
+ expect(subject.new.token_protected!).to_not be(false)
70
+ end
71
+
72
+ it 'allows #enterprise_protected! methods for the scoped domain' do
73
+ expect(subject.new.enterprise_protected!('example.com')).to_not be(false)
74
+ end
75
+
76
+ it 'halts #enterprise_protected! methods for the wrong scoped domain' do
77
+ expect(subject.new.enterprise_protected!('foo.com')).to be(false)
78
+ end
79
+
80
+ it 'halts #internal_protected! methods' do
81
+ expect(subject.new.internal_protected!).to be(false)
82
+ end
83
+
84
+ it 'halts #admin_protected! methods' do
85
+ expect(subject.new.admin_protected!).to be(false)
86
+ end
87
+ end
88
+ end
89
+
90
+ def encode(payload)
91
+ JWT.encode(
92
+ payload,
93
+ ENV['JWT_HMAC_SECRET'],
94
+ 'HS256',
95
+ )
96
+ end
97
+ end
@@ -14,4 +14,16 @@ describe Osso::Models::IdentityProvider do
14
14
  )
15
15
  end
16
16
  end
17
+
18
+ describe '#saml_options' do
19
+ it 'returns the required args' do
20
+ expect(subject.saml_options).
21
+ to match(
22
+ domain: subject.domain,
23
+ idp_cert: subject.sso_cert,
24
+ idp_sso_target_url: subject.sso_url,
25
+ issuer: subject.domain,
26
+ )
27
+ end
28
+ end
17
29
  end
@@ -63,6 +63,24 @@ describe Osso::Auth do
63
63
  )
64
64
  end.to change { Osso::Models::AuthorizationCode.count }.by(1)
65
65
  end
66
+
67
+ describe 'for an IDP initiated login' do
68
+ it 'redirects with a default state' do
69
+ mock_saml_omniauth
70
+
71
+ post(
72
+ "/auth/saml/#{okta_provider.id}/callback",
73
+ nil,
74
+ {
75
+ 'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
76
+ 'identity_provider' => okta_provider,
77
+ },
78
+ )
79
+ expect(last_response).to be_redirect
80
+ follow_redirect!
81
+ expect(last_request.url).to match(/.*state=IDP_INITIATED$/)
82
+ end
83
+ end
66
84
  end
67
85
 
68
86
  describe 'on subsequent authentications' do
@@ -8,7 +8,10 @@ describe Osso::Oauth do
8
8
  describe 'get /oauth/authorize' do
9
9
  describe 'with a valid client ID and redirect URI' do
10
10
  describe 'for a domain that does not belong to an enterprise' do
11
- it '404s' do
11
+ # TODO: better error handling and test
12
+ it 'renders an error page' do
13
+ described_class.set(:views, spec_views)
14
+
12
15
  create(:enterprise_with_okta, domain: 'foo.com')
13
16
 
14
17
  get(
@@ -19,7 +22,7 @@ describe Osso::Oauth do
19
22
  redirect_uri: client.redirect_uri_values.sample,
20
23
  )
21
24
 
22
- expect(last_response.status).to eq(404)
25
+ expect(last_response.status).to eq(200)
23
26
  end
24
27
  end
25
28
 
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
3
6
  require 'database_cleaner/active_record'
4
7
  require 'factory_bot'
5
8
  require 'faker'
File without changes
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.3.14
4
+ version: 0.0.3.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Bauch
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-13 00:00:00.000000000 Z
11
+ date: 2020-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -226,6 +226,7 @@ email:
226
226
  executables:
227
227
  - annotate
228
228
  - console
229
+ - publish
229
230
  - setup
230
231
  extensions: []
231
232
  extra_rdoc_files: []
@@ -246,6 +247,7 @@ files:
246
247
  - Rakefile
247
248
  - bin/annotate
248
249
  - bin/console
250
+ - bin/publish
249
251
  - bin/setup
250
252
  - config/database.yml
251
253
  - db/schema.rb
@@ -268,6 +270,7 @@ files:
268
270
  - lib/osso/db/migrate/20200722230116_add_identity_provider_status_enum_and_use_on_identity_providers.rb
269
271
  - lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb
270
272
  - lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb
273
+ - lib/osso/db/migrate/20200826201852_create_app_config.rb
271
274
  - lib/osso/graphql/.DS_Store
272
275
  - lib/osso/graphql/mutation.rb
273
276
  - lib/osso/graphql/mutations.rb
@@ -280,13 +283,17 @@ files:
280
283
  - lib/osso/graphql/mutations/delete_oauth_client.rb
281
284
  - lib/osso/graphql/mutations/regenerate_oauth_credentials.rb
282
285
  - lib/osso/graphql/mutations/set_redirect_uris.rb
286
+ - lib/osso/graphql/mutations/update_app_config.rb
283
287
  - lib/osso/graphql/query.rb
284
288
  - lib/osso/graphql/resolvers.rb
289
+ - lib/osso/graphql/resolvers/base_resolver.rb
285
290
  - lib/osso/graphql/resolvers/enterprise_account.rb
286
291
  - lib/osso/graphql/resolvers/enterprise_accounts.rb
287
292
  - lib/osso/graphql/resolvers/oauth_clients.rb
288
293
  - lib/osso/graphql/schema.rb
289
294
  - lib/osso/graphql/types.rb
295
+ - lib/osso/graphql/types/admin_user.rb
296
+ - lib/osso/graphql/types/app_config.rb
290
297
  - lib/osso/graphql/types/base_connection.rb
291
298
  - lib/osso/graphql/types/base_enum.rb
292
299
  - lib/osso/graphql/types/base_input_object.rb
@@ -298,13 +305,13 @@ files:
298
305
  - lib/osso/graphql/types/oauth_client.rb
299
306
  - lib/osso/graphql/types/redirect_uri.rb
300
307
  - lib/osso/graphql/types/redirect_uri_input.rb
301
- - lib/osso/graphql/types/user.rb
302
308
  - lib/osso/helpers/auth.rb
303
309
  - lib/osso/helpers/helpers.rb
304
310
  - lib/osso/lib/app_config.rb
305
311
  - lib/osso/lib/oauth2_token.rb
306
312
  - lib/osso/lib/route_map.rb
307
313
  - lib/osso/models/access_token.rb
314
+ - lib/osso/models/app_config.rb
308
315
  - lib/osso/models/authorization_code.rb
309
316
  - lib/osso/models/enterprise_account.rb
310
317
  - lib/osso/models/identity_provider.rb
@@ -338,6 +345,7 @@ files:
338
345
  - spec/graphql/query/enterprise_accounts_spec.rb
339
346
  - spec/graphql/query/identity_provider_spec.rb
340
347
  - spec/graphql/query/oauth_clients_spec.rb
348
+ - spec/helpers/auth_spec.rb
341
349
  - spec/models/azure_saml_provider_spec.rb
342
350
  - spec/models/identity_provider_spec.rb
343
351
  - spec/models/okta_saml_provider_spec.rb
@@ -348,11 +356,12 @@ files:
348
356
  - spec/spec_helper.rb
349
357
  - spec/support/spec_app.rb
350
358
  - spec/support/views/admin.erb
359
+ - spec/support/views/error.erb
351
360
  homepage: https://github.com/enterprise-oss/osso-rb
352
361
  licenses:
353
362
  - MIT
354
363
  metadata: {}
355
- post_install_message:
364
+ post_install_message:
356
365
  rdoc_options: []
357
366
  require_paths:
358
367
  - lib
@@ -368,7 +377,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
368
377
  version: '0'
369
378
  requirements: []
370
379
  rubygems_version: 3.0.3
371
- signing_key:
380
+ signing_key:
372
381
  specification_version: 4
373
382
  summary: Main functionality for Osso
374
383
  test_files: []