osso 0.0.3.4 → 0.0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.yml +6 -1
  3. data/.rubocop.yml +1 -2
  4. data/Gemfile.lock +5 -1
  5. data/bin/annotate +1 -0
  6. data/bin/console +4 -3
  7. data/config/database.yml +2 -2
  8. data/db/schema.rb +90 -1
  9. data/lib/osso.rb +1 -0
  10. data/lib/osso/db/migrate/20200328143305_create_identity_providers.rb +12 -0
  11. data/lib/osso/db/migrate/20200411184535_add_provider_id_to_users.rb +2 -2
  12. data/lib/osso/db/migrate/20200411192645_create_enterprise_accounts.rb +1 -1
  13. data/lib/osso/db/migrate/20200502135008_add_oauth_client_id_to_enterprise_accounts_and_identity_providers.rb +6 -0
  14. data/lib/osso/db/migrate/20200714223226_add_identity_provider_service_enum.rb +17 -0
  15. data/lib/osso/db/migrate/20200715154211_rename_idp_fields_on_identity_provider_to_sso.rb +6 -0
  16. data/lib/osso/db/migrate/20200715205801_add_name_to_enterprise_account.rb +5 -0
  17. data/lib/osso/db/migrate/20200722230116_add_identity_provider_status_enum_and_use_on_identity_providers.rb +15 -0
  18. data/lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb +35 -0
  19. data/lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb +9 -0
  20. data/lib/osso/graphql/mutation.rb +5 -2
  21. data/lib/osso/graphql/mutations.rb +5 -1
  22. data/lib/osso/graphql/mutations/base_mutation.rb +24 -7
  23. data/lib/osso/graphql/mutations/configure_identity_provider.rb +19 -13
  24. data/lib/osso/graphql/mutations/create_enterprise_account.rb +25 -0
  25. data/lib/osso/graphql/mutations/create_identity_provider.rb +9 -7
  26. data/lib/osso/graphql/mutations/create_oauth_client.rb +30 -0
  27. data/lib/osso/graphql/mutations/delete_enterprise_account.rb +34 -0
  28. data/lib/osso/graphql/mutations/delete_oauth_client.rb +30 -0
  29. data/lib/osso/graphql/query.rb +2 -2
  30. data/lib/osso/graphql/resolvers/oauth_clients.rb +2 -2
  31. data/lib/osso/graphql/schema.rb +5 -1
  32. data/lib/osso/graphql/types.rb +2 -0
  33. data/lib/osso/graphql/types/base_input_object.rb +10 -0
  34. data/lib/osso/graphql/types/base_object.rb +2 -0
  35. data/lib/osso/graphql/types/enterprise_account.rb +5 -5
  36. data/lib/osso/graphql/types/identity_provider.rb +6 -13
  37. data/lib/osso/graphql/types/identity_provider_service.rb +1 -1
  38. data/lib/osso/graphql/types/identity_provider_status.rb +14 -0
  39. data/lib/osso/graphql/types/oauth_client.rb +13 -1
  40. data/lib/osso/helpers/auth.rb +16 -15
  41. data/lib/osso/lib/app_config.rb +1 -1
  42. data/lib/osso/lib/route_map.rb +28 -0
  43. data/lib/osso/models/access_token.rb +18 -0
  44. data/lib/osso/models/authorization_code.rb +20 -0
  45. data/lib/osso/models/enterprise_account.rb +24 -4
  46. data/lib/osso/models/identity_provider.rb +77 -0
  47. data/lib/osso/models/models.rb +3 -1
  48. data/lib/osso/models/oauth_client.rb +19 -3
  49. data/lib/osso/models/redirect_uri.rb +17 -0
  50. data/lib/osso/models/user.rb +25 -3
  51. data/lib/osso/routes/admin.rb +18 -15
  52. data/lib/osso/routes/auth.rb +30 -27
  53. data/lib/osso/routes/oauth.rb +50 -45
  54. data/lib/osso/version.rb +1 -1
  55. data/osso-rb.gemspec +3 -3
  56. data/spec/factories/enterprise_account.rb +5 -4
  57. data/spec/factories/identity_providers.rb +71 -0
  58. data/spec/factories/user.rb +1 -1
  59. data/spec/graphql/mutations/configure_identity_provider_spec.rb +75 -0
  60. data/spec/graphql/mutations/create_enterprise_account_spec.rb +68 -0
  61. data/spec/graphql/mutations/create_identity_provider_spec.rb +104 -0
  62. data/spec/graphql/mutations/create_oauth_client_spec.rb +55 -0
  63. data/spec/graphql/mutations/delete_enterprise_account_spec.rb +63 -0
  64. data/spec/graphql/mutations/delete_oauth_client_spec.rb +51 -0
  65. data/spec/graphql/query/enterprise_account_spec.rb +68 -0
  66. data/spec/graphql/query/enterprise_accounts_spec.rb +44 -0
  67. data/spec/graphql/query/identity_provider_spec.rb +65 -0
  68. data/spec/graphql/query/oauth_clients_spec.rb +50 -0
  69. data/spec/models/azure_saml_provider_spec.rb +14 -14
  70. data/spec/models/identity_provider_spec.rb +17 -0
  71. data/spec/models/okta_saml_provider_spec.rb +15 -15
  72. data/spec/routes/admin_spec.rb +2 -0
  73. data/spec/routes/auth_spec.rb +9 -9
  74. data/spec/routes/oauth_spec.rb +1 -1
  75. data/spec/spec_helper.rb +4 -5
  76. data/spec/support/spec_app.rb +9 -0
  77. metadata +47 -16
  78. data/lib/osso/db/migrate/20200328143303_create_oauth_tables.rb +0 -57
  79. data/lib/osso/db/migrate/20200411144528_create_saml_providers.rb +0 -13
  80. data/lib/osso/db/migrate/20200413153029_add_oauth_client_reference_to_saml_providers.rb +0 -5
  81. data/lib/osso/db/migrate/20200501203026_drop_null_constraints_from_saml_provider.rb +0 -7
  82. data/lib/osso/db/migrate/20200501204047_drop_acs_url.rb +0 -5
  83. data/lib/osso/db/migrate/20200502135008_add_oauth_client_id_to_enterprise_account.rb +0 -5
  84. data/lib/osso/db/migrate/20200601131227_drop_null_constraint_from_saml_providers_provider.rb +0 -7
  85. data/lib/osso/db/schema.rb +0 -132
  86. data/lib/osso/graphql/mutations/set_saml_provider.rb +0 -27
  87. data/lib/osso/models/saml_provider.rb +0 -52
  88. data/lib/osso/models/saml_providers/azure_saml_provider.rb +0 -22
  89. data/lib/osso/models/saml_providers/okta_saml_provider.rb +0 -23
  90. data/spec/factories/saml_providers.rb +0 -46
  91. data/spec/models/saml_provider_spec.rb +0 -31
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'DeleteEnterpriseAccount' do
7
+ let(:domain) { Faker::Internet.domain_name }
8
+ let!(:enterprise_account) { create(:enterprise_account, domain: domain) }
9
+ let(:variables) do
10
+ {
11
+ input: {
12
+ id: enterprise_account.id,
13
+ },
14
+ }
15
+ end
16
+
17
+ let(:mutation) do
18
+ <<~GRAPHQL
19
+ mutation DeleteEnterpriseAccount($input: DeleteEnterpriseAccountInput!) {
20
+ deleteEnterpriseAccount(input: $input) {
21
+ enterpriseAccount {
22
+ id
23
+ }
24
+ }
25
+ }
26
+ GRAPHQL
27
+ end
28
+
29
+ subject do
30
+ described_class.execute(
31
+ mutation,
32
+ variables: variables,
33
+ context: { scope: current_scope },
34
+ )
35
+ end
36
+
37
+ describe 'for an admin user' do
38
+ let(:current_scope) { :admin }
39
+ it 'deletes an Enterprise Account' do
40
+ expect { subject }.to change { Osso::Models::EnterpriseAccount.count }.by(-1)
41
+ expect(subject.dig('data', 'createEnterpriseAccount', 'enterpriseAccount')).
42
+ to be_nil
43
+ end
44
+ end
45
+
46
+ describe 'for an email scoped user' do
47
+ let(:current_scope) { domain }
48
+
49
+ it 'deletes the Enterprise Account' do
50
+ expect { subject }.to change { Osso::Models::EnterpriseAccount.count }.by(-1)
51
+ expect(subject.dig('data', 'createEnterpriseAccount', 'enterpriseAccount')).
52
+ to be_nil
53
+ end
54
+ end
55
+ describe 'for the wrong email scoped user' do
56
+ let(:current_scope) { 'foo.com' }
57
+
58
+ it 'does not delete the Enterprise Account' do
59
+ expect { subject }.to_not(change { Osso::Models::EnterpriseAccount.count })
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'DeleteOauthClient' do
7
+ let!(:oauth_client) { create(:oauth_client) }
8
+ let(:variables) do
9
+ {
10
+ input: {
11
+ id: oauth_client.id,
12
+ },
13
+ }
14
+ end
15
+
16
+ let(:mutation) do
17
+ <<~GRAPHQL
18
+ mutation DeleteOauthClient($input: DeleteOauthClientInput!) {
19
+ deleteOauthClient(input: $input) {
20
+ oauthClient {
21
+ id
22
+ }
23
+ }
24
+ }
25
+ GRAPHQL
26
+ end
27
+
28
+ subject do
29
+ described_class.execute(
30
+ mutation,
31
+ variables: variables,
32
+ context: { scope: current_scope },
33
+ )
34
+ end
35
+
36
+ describe 'for an admin user' do
37
+ let(:current_scope) { :admin }
38
+ it 'deletes the OauthClient' do
39
+ expect { subject }.to change { Osso::Models::OauthClient.count }.by(-1)
40
+ end
41
+ end
42
+
43
+ describe 'for an email scoped user' do
44
+ let(:current_scope) { 'foo.com' }
45
+
46
+ it 'does not create an OauthClient Account' do
47
+ expect { subject }.to_not(change { Osso::Models::OauthClient.count })
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'EnterpriseAccount' do
7
+ let(:domain) { Faker::Internet.domain_name }
8
+ let(:variables) { { domain: domain } }
9
+ let(:query) do
10
+ <<~GRAPHQL
11
+ query EnterpriseAccount($domain: String!) {
12
+ enterpriseAccount(domain: $domain) {
13
+ domain
14
+ id
15
+ identityProviders {
16
+ id
17
+ service
18
+ domain
19
+ acsUrl
20
+ ssoCert
21
+ ssoUrl
22
+ status
23
+ }
24
+ name
25
+ status
26
+ }
27
+ }
28
+ GRAPHQL
29
+ end
30
+
31
+ before do
32
+ create(:enterprise_account)
33
+ create(:enterprise_account, domain: domain)
34
+ end
35
+
36
+ subject do
37
+ described_class.execute(
38
+ query,
39
+ variables: variables,
40
+ context: { scope: current_scope },
41
+ )
42
+ end
43
+
44
+ describe 'for an admin user' do
45
+ let(:current_scope) { :admin }
46
+ it 'returns Enterprise Account for domain' do
47
+ expect(subject['errors']).to be_nil
48
+ expect(subject.dig('data', 'enterpriseAccount', 'domain')).to eq(domain)
49
+ end
50
+ end
51
+
52
+ describe 'for an email scoped user' do
53
+ let(:current_scope) { domain }
54
+ it 'returns Enterprise Account for domain' do
55
+ expect(subject['errors']).to be_nil
56
+ expect(subject.dig('data', 'enterpriseAccount', 'domain')).to eq(domain)
57
+ end
58
+ end
59
+
60
+ 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
64
+ expect(subject.dig('data', 'enterpriseAccount')).to be_nil
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'EnterpriseAccounts' do
7
+ describe 'for an admin user' do
8
+ let(:current_scope) { :admin }
9
+
10
+ it 'returns Enterprise Accounts' do
11
+ create_list(:enterprise_account, 2)
12
+
13
+ query = <<~GRAPHQL
14
+ query EnterpriseAccounts {
15
+ enterpriseAccounts {
16
+ domain
17
+ id
18
+ identityProviders {
19
+ id
20
+ service
21
+ domain
22
+ acsUrl
23
+ ssoCert
24
+ ssoUrl
25
+ status
26
+ }
27
+ name
28
+ status
29
+ }
30
+ }
31
+ GRAPHQL
32
+
33
+ response = described_class.execute(
34
+ query,
35
+ variables: nil,
36
+ context: { scope: current_scope },
37
+ )
38
+
39
+ expect(response['errors']).to be_nil
40
+ expect(response.dig('data', 'enterpriseAccounts').count).to eq(2)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'Identity Provider' do
7
+ let(:id) { Faker::Internet.uuid }
8
+ let(:domain) { Faker::Internet.domain_name }
9
+ let(:variables) { { id: id } }
10
+ let(:query) do
11
+ <<~GRAPHQL
12
+ query IdentityProvider($id: ID!) {
13
+ identityProvider(id: $id) {
14
+ id
15
+ service
16
+ domain
17
+ acsUrl
18
+ ssoCert
19
+ ssoUrl
20
+ status
21
+ }
22
+ }
23
+ GRAPHQL
24
+ end
25
+
26
+ before do
27
+ create(:identity_provider)
28
+ create(:identity_provider, id: id, domain: domain)
29
+ end
30
+
31
+ subject do
32
+ described_class.execute(
33
+ query,
34
+ variables: variables,
35
+ context: { scope: current_scope },
36
+ )
37
+ end
38
+
39
+ describe 'for an admin user' do
40
+ let(:current_scope) { :admin }
41
+ it 'returns Identity Provider for id' do
42
+ expect(subject['errors']).to be_nil
43
+ expect(subject.dig('data', 'identityProvider', 'id')).to eq(id)
44
+ end
45
+ end
46
+
47
+ describe 'for an email scoped user' do
48
+ let(:current_scope) { domain }
49
+
50
+ it 'returns Enterprise Account for domain' do
51
+ expect(subject['errors']).to be_nil
52
+ expect(subject.dig('data', 'identityProvider', 'domain')).to eq(domain)
53
+ end
54
+ end
55
+
56
+ describe 'for the wrong email scoped user' do
57
+ let(:current_scope) { 'bar.com' }
58
+
59
+ it 'returns Enterprise Account for domain' do
60
+ expect(subject['errors']).to_not be_empty
61
+ expect(subject.dig('data', 'enterpriseAccount')).to be_nil
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::GraphQL::Schema do
6
+ describe 'OAuthClients' do
7
+ let(:query) do
8
+ <<~GRAPHQL
9
+ query OAuthClients {
10
+ oauthClients {
11
+ name
12
+ id
13
+ clientSecret
14
+ clientId
15
+ }
16
+ }
17
+ GRAPHQL
18
+ end
19
+
20
+ before do
21
+ create_list(:oauth_client, 2)
22
+ end
23
+
24
+ subject do
25
+ described_class.execute(
26
+ query,
27
+ variables: nil,
28
+ context: { scope: current_scope },
29
+ )
30
+ end
31
+
32
+ describe 'for an admin user' do
33
+ let(:current_scope) { :admin }
34
+
35
+ it 'returns Oauth Clients' do
36
+ expect(subject['errors']).to be_nil
37
+ expect(subject.dig('data', 'oauthClients').count).to eq(2)
38
+ end
39
+ end
40
+
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
46
+ expect(subject.dig('data', 'oauthClients')).to be_nil
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,18 +2,18 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Osso::Models::AzureSamlProvider do
6
- subject { create(:azure_saml_provider) }
5
+ # describe Osso::Models::AzureSamlProvider do
6
+ # subject { create(:azure_identity_provider) }
7
7
 
8
- describe '#saml_options' do
9
- it 'returns the required args' do
10
- expect(subject.saml_options).
11
- to match(
12
- domain: subject.domain,
13
- idp_cert: subject.idp_cert,
14
- idp_sso_target_url: subject.idp_sso_target_url,
15
- issuer: "id:#{subject.id}",
16
- )
17
- end
18
- end
19
- end
8
+ # describe '#saml_options' do
9
+ # it 'returns the required args' do
10
+ # expect(subject.saml_options).
11
+ # to match(
12
+ # domain: subject.domain,
13
+ # idp_cert: subject.idp_cert,
14
+ # idp_sso_target_url: subject.idp_sso_target_url,
15
+ # issuer: "id:#{subject.id}",
16
+ # )
17
+ # end
18
+ # end
19
+ # end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Osso::Models::IdentityProvider do
6
+ subject { create(:okta_identity_provider) }
7
+
8
+ describe '#assertion_consumer_service_url' do
9
+ it 'returns the expected URI' do
10
+ ENV['BASE_URL'] = 'https://example.com'
11
+
12
+ expect(subject.assertion_consumer_service_url).to eq(
13
+ "https://example.com/auth/saml/#{subject.id}/callback",
14
+ )
15
+ end
16
+ end
17
+ end
@@ -2,19 +2,19 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Osso::Models::OktaSamlProvider do
6
- subject { create(:okta_saml_provider) }
5
+ # describe Osso::Models::OktaSamlProvider do
6
+ # subject { create(:okta_identity_provider) }
7
7
 
8
- describe '#saml_options' do
9
- it 'returns the required args' do
10
- expect(subject.saml_options).
11
- to match(
12
- domain: subject.domain,
13
- idp_cert: subject.idp_cert,
14
- idp_sso_target_url: subject.idp_sso_target_url,
15
- issuer: subject.id,
16
- name_identifier_format: described_class::NAME_FORMAT,
17
- )
18
- end
19
- end
20
- end
8
+ # describe '#saml_options' do
9
+ # it 'returns the required args' do
10
+ # expect(subject.saml_options).
11
+ # to match(
12
+ # domain: subject.domain,
13
+ # idp_cert: subject.idp_cert,
14
+ # idp_sso_target_url: subject.idp_sso_target_url,
15
+ # issuer: subject.id,
16
+ # name_identifier_format: described_class::NAME_FORMAT,
17
+ # )
18
+ # end
19
+ # end
20
+ # end
@@ -25,7 +25,9 @@ describe Osso::Admin do
25
25
  get('/admin', token: SecureRandom.hex(32))
26
26
 
27
27
  expect(last_response).to be_redirect
28
+
28
29
  follow_redirect!
30
+
29
31
  expect(last_request.url).to eq(jwt_url)
30
32
  end
31
33
 
@@ -6,7 +6,7 @@ describe Osso::Auth do
6
6
  describe 'post /auth/saml/:uuid/callback' do
7
7
  describe 'for an Okta SAML provider' do
8
8
  let(:enterprise) { create(:enterprise_with_okta) }
9
- let(:okta_provider) { enterprise.saml_providers.first }
9
+ let(:okta_provider) { enterprise.identity_providers.first }
10
10
 
11
11
  describe "on the user's first authentication" do
12
12
  it 'creates a user' do
@@ -18,7 +18,7 @@ describe Osso::Auth do
18
18
  nil,
19
19
  {
20
20
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
21
- 'saml_provider' => okta_provider,
21
+ 'identity_provider' => okta_provider,
22
22
  },
23
23
  )
24
24
  end.to change { Osso::Models::User.count }.by(1)
@@ -33,7 +33,7 @@ describe Osso::Auth do
33
33
  nil,
34
34
  {
35
35
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
36
- 'saml_provider' => okta_provider,
36
+ 'identity_provider' => okta_provider,
37
37
  },
38
38
  )
39
39
  end.to change { Osso::Models::AuthorizationCode.count }.by(1)
@@ -42,8 +42,8 @@ describe Osso::Auth do
42
42
 
43
43
  describe 'on subsequent authentications' do
44
44
  let!(:enterprise) { create(:enterprise_with_okta) }
45
- let!(:okta_provider) { enterprise.saml_providers.first }
46
- let(:user) { create(:user, saml_provider_id: okta_provider.id) }
45
+ let!(:okta_provider) { enterprise.identity_providers.first }
46
+ let(:user) { create(:user, identity_provider_id: okta_provider.id) }
47
47
 
48
48
  before do
49
49
  mock_saml_omniauth(email: user.email, id: user.idp_id)
@@ -56,7 +56,7 @@ describe Osso::Auth do
56
56
  nil,
57
57
  {
58
58
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
59
- 'saml_provider' => okta_provider,
59
+ 'identity_provider' => okta_provider,
60
60
  },
61
61
  )
62
62
  end.to_not(change { Osso::Models::User.count })
@@ -78,7 +78,7 @@ describe Osso::Auth do
78
78
  nil,
79
79
  {
80
80
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
81
- 'saml_provider' => azure_provider,
81
+ 'identity_provider' => azure_provider,
82
82
  },
83
83
  )
84
84
  end.to change { Osso::Models::User.count }.by(1)
@@ -88,7 +88,7 @@ describe Osso::Auth do
88
88
  describe 'on subsequent authentications' do
89
89
  let!(:enterprise) { create(:enterprise_with_azure) }
90
90
  let!(:azure_provider) { enterprise.provider }
91
- let(:user) { create(:user, saml_provider_id: azure_provider.id) }
91
+ let(:user) { create(:user, identity_provider_id: azure_provider.id) }
92
92
 
93
93
  before do
94
94
  mock_saml_omniauth(email: user.email, id: user.idp_id)
@@ -101,7 +101,7 @@ describe Osso::Auth do
101
101
  nil,
102
102
  {
103
103
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
104
- 'saml_provider' => azure_provider,
104
+ 'identity_provider' => azure_provider,
105
105
  },
106
106
  )
107
107
  end.to_not(change { Osso::Models::User.count })