osso 0.0.3.7 → 0.0.3.12
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 +5 -3
- data/Gemfile.lock +5 -1
- data/bin/annotate +1 -0
- data/db/schema.rb +11 -54
- data/lib/osso/db/migrate/20200714223226_add_identity_provider_service_enum.rb +1 -1
- data/lib/osso/db/migrate/20200722230116_add_identity_provider_status_enum_and_use_on_identity_providers.rb +15 -0
- data/lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb +35 -0
- data/lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb +9 -0
- data/lib/osso/graphql/mutation.rb +7 -1
- data/lib/osso/graphql/mutations.rb +7 -1
- data/lib/osso/graphql/mutations/add_redirect_uris_to_oauth_client.rb +39 -0
- data/lib/osso/graphql/mutations/configure_identity_provider.rb +1 -1
- data/lib/osso/graphql/mutations/create_oauth_client.rb +30 -0
- data/lib/osso/graphql/mutations/delete_enterprise_account.rb +34 -0
- data/lib/osso/graphql/mutations/delete_oauth_client.rb +30 -0
- data/lib/osso/graphql/mutations/delete_redirect_uri.rb +38 -0
- data/lib/osso/graphql/mutations/mark_redirect_uri_primary.rb +34 -0
- data/lib/osso/graphql/mutations/regenerate_oauth_credentials.rb +31 -0
- data/lib/osso/graphql/query.rb +15 -2
- data/lib/osso/graphql/resolvers/enterprise_accounts.rb +12 -4
- data/lib/osso/graphql/resolvers/oauth_clients.rb +1 -1
- data/lib/osso/graphql/types.rb +3 -0
- data/lib/osso/graphql/types/base_connection.rb +15 -0
- data/lib/osso/graphql/types/base_object.rb +4 -0
- data/lib/osso/graphql/types/identity_provider.rb +1 -5
- data/lib/osso/graphql/types/identity_provider_status.rb +14 -0
- data/lib/osso/graphql/types/oauth_client.rb +14 -1
- data/lib/osso/graphql/types/redirect_uri.rb +23 -0
- data/lib/osso/helpers/auth.rb +13 -12
- data/lib/osso/models/access_token.rb +18 -0
- data/lib/osso/models/authorization_code.rb +20 -0
- data/lib/osso/models/enterprise_account.rb +20 -0
- data/lib/osso/models/identity_provider.rb +29 -0
- data/lib/osso/models/models.rb +2 -0
- data/lib/osso/models/oauth_client.rb +20 -10
- data/lib/osso/models/redirect_uri.rb +17 -0
- data/lib/osso/models/user.rb +22 -0
- data/lib/osso/routes/admin.rb +6 -0
- data/lib/osso/routes/auth.rb +1 -1
- data/lib/osso/version.rb +1 -1
- data/osso-rb.gemspec +1 -0
- data/spec/factories/identity_providers.rb +22 -0
- data/spec/graphql/mutations/configure_identity_provider_spec.rb +3 -3
- data/spec/graphql/mutations/create_oauth_client_spec.rb +55 -0
- data/spec/graphql/mutations/delete_enterprise_account_spec.rb +63 -0
- data/spec/graphql/mutations/delete_oauth_client_spec.rb +51 -0
- data/spec/graphql/query/enterprise_account_spec.rb +1 -1
- data/spec/graphql/query/enterprise_accounts_spec.rb +32 -18
- data/spec/graphql/query/identity_provider_spec.rb +2 -2
- data/spec/graphql/query/{oauth_clients_account_spec.rb → oauth_clients_spec.rb} +2 -0
- data/spec/routes/auth_spec.rb +25 -0
- metadata +35 -8
- data/lib/osso/db/migrate/20200328143303_create_oauth_tables.rb +0 -57
- data/lib/osso/graphql/mutations/set_identity_provider.rb +0 -27
- data/lib/osso/models/saml_provider.rb +0 -49
- data/lib/osso/models/saml_providers/azure_saml_provider.rb +0 -22
- data/lib/osso/models/saml_providers/okta_saml_provider.rb +0 -23
@@ -18,3 +18,20 @@ module Osso
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
# == Schema Information
|
23
|
+
#
|
24
|
+
# Table name: redirect_uris
|
25
|
+
#
|
26
|
+
# id :uuid not null, primary key
|
27
|
+
# uri :string not null
|
28
|
+
# primary :boolean default(FALSE), not null
|
29
|
+
# oauth_client_id :uuid
|
30
|
+
# created_at :datetime not null
|
31
|
+
# updated_at :datetime not null
|
32
|
+
#
|
33
|
+
# Indexes
|
34
|
+
#
|
35
|
+
# index_redirect_uris_on_oauth_client_id (oauth_client_id)
|
36
|
+
# index_redirect_uris_on_uri_and_primary (uri,primary) UNIQUE
|
37
|
+
#
|
data/lib/osso/models/user.rb
CHANGED
@@ -22,3 +22,25 @@ module Osso
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
# == Schema Information
|
27
|
+
#
|
28
|
+
# Table name: users
|
29
|
+
#
|
30
|
+
# id :uuid not null, primary key
|
31
|
+
# email :string not null
|
32
|
+
# idp_id :string not null
|
33
|
+
# identity_provider_id :uuid
|
34
|
+
# enterprise_account_id :uuid
|
35
|
+
# created_at :datetime not null
|
36
|
+
# updated_at :datetime not null
|
37
|
+
#
|
38
|
+
# Indexes
|
39
|
+
#
|
40
|
+
# index_users_on_email_and_idp_id (email,idp_id) UNIQUE
|
41
|
+
# index_users_on_enterprise_account_id (enterprise_account_id)
|
42
|
+
#
|
43
|
+
# Foreign Keys
|
44
|
+
#
|
45
|
+
# fk_rails_... (identity_provider_id => identity_providers.id)
|
46
|
+
#
|
data/lib/osso/routes/admin.rb
CHANGED
data/lib/osso/routes/auth.rb
CHANGED
@@ -23,7 +23,7 @@ module Osso
|
|
23
23
|
self,
|
24
24
|
provider_name: 'saml',
|
25
25
|
identity_provider_id_regex: UUID_REGEXP,
|
26
|
-
path_prefix: '/saml',
|
26
|
+
path_prefix: '/auth/saml',
|
27
27
|
callback_suffix: 'callback',
|
28
28
|
) do |identity_provider_id, _env|
|
29
29
|
provider = Models::IdentityProvider.find(identity_provider_id)
|
data/lib/osso/version.rb
CHANGED
data/osso-rb.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_runtime_dependency 'sinatra-activerecord'
|
29
29
|
spec.add_runtime_dependency 'sinatra-contrib'
|
30
30
|
|
31
|
+
spec.add_development_dependency 'annotate', '~> 3.1'
|
31
32
|
spec.add_development_dependency 'bundler', '~> 2.1'
|
32
33
|
spec.add_development_dependency 'pry'
|
33
34
|
|
@@ -47,3 +47,25 @@ FactoryBot.define do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
# == Schema Information
|
52
|
+
#
|
53
|
+
# Table name: identity_providers
|
54
|
+
#
|
55
|
+
# id :uuid not null, primary key
|
56
|
+
# service :string
|
57
|
+
# domain :string not null
|
58
|
+
# sso_url :string
|
59
|
+
# sso_cert :text
|
60
|
+
# enterprise_account_id :uuid
|
61
|
+
# oauth_client_id :uuid
|
62
|
+
# status :enum default("PENDING")
|
63
|
+
# created_at :datetime
|
64
|
+
# updated_at :datetime
|
65
|
+
#
|
66
|
+
# Indexes
|
67
|
+
#
|
68
|
+
# index_identity_providers_on_domain (domain)
|
69
|
+
# index_identity_providers_on_enterprise_account_id (enterprise_account_id)
|
70
|
+
# index_identity_providers_on_oauth_client_id (oauth_client_id)
|
71
|
+
#
|
@@ -23,7 +23,7 @@ describe Osso::GraphQL::Schema do
|
|
23
23
|
identityProvider {
|
24
24
|
id
|
25
25
|
domain
|
26
|
-
|
26
|
+
status
|
27
27
|
enterpriseAccountId
|
28
28
|
service
|
29
29
|
acsUrl
|
@@ -46,8 +46,8 @@ describe Osso::GraphQL::Schema do
|
|
46
46
|
describe 'for an admin user' do
|
47
47
|
let(:current_scope) { :admin }
|
48
48
|
it 'configures an identity provider' do
|
49
|
-
expect(subject.dig('data', 'configureIdentityProvider', 'identityProvider', '
|
50
|
-
to
|
49
|
+
expect(subject.dig('data', 'configureIdentityProvider', 'identityProvider', 'status')).
|
50
|
+
to eq('Configured')
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Osso::GraphQL::Schema do
|
6
|
+
describe 'CreateOauthClient' do
|
7
|
+
let(:variables) do
|
8
|
+
{
|
9
|
+
input: {
|
10
|
+
name: Faker::Company.name,
|
11
|
+
},
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:mutation) do
|
16
|
+
<<~GRAPHQL
|
17
|
+
mutation CreateOauthClient($input: CreateOauthClientInput!) {
|
18
|
+
createOauthClient(input: $input) {
|
19
|
+
oauthClient {
|
20
|
+
id
|
21
|
+
name
|
22
|
+
clientId
|
23
|
+
clientSecret
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
GRAPHQL
|
28
|
+
end
|
29
|
+
|
30
|
+
subject do
|
31
|
+
described_class.execute(
|
32
|
+
mutation,
|
33
|
+
variables: variables,
|
34
|
+
context: { scope: current_scope },
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'for an admin user' do
|
39
|
+
let(:current_scope) { :admin }
|
40
|
+
it 'creates an OauthClient' do
|
41
|
+
expect { subject }.to change { Osso::Models::OauthClient.count }.by(1)
|
42
|
+
expect(subject.dig('data', 'createOauthClient', 'oauthClient', 'clientId')).
|
43
|
+
to_not be_nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'for an email scoped user' do
|
48
|
+
let(:current_scope) { 'foo.com' }
|
49
|
+
|
50
|
+
it 'does not create an OauthClient Account' do
|
51
|
+
expect { subject }.to_not(change { Osso::Models::OauthClient.count })
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -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
|
@@ -7,37 +7,51 @@ describe Osso::GraphQL::Schema do
|
|
7
7
|
describe 'for an admin user' do
|
8
8
|
let(:current_scope) { :admin }
|
9
9
|
|
10
|
-
it 'returns Enterprise Accounts' do
|
11
|
-
|
10
|
+
it 'returns paginated Enterprise Accounts' do
|
11
|
+
%w[A B C].map do |name|
|
12
|
+
create(:enterprise_account, name: name)
|
13
|
+
end
|
12
14
|
|
13
15
|
query = <<~GRAPHQL
|
14
|
-
query EnterpriseAccounts {
|
15
|
-
enterpriseAccounts {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
query EnterpriseAccounts($first: Int, $sortColumn: String, $sortOrder: String) {
|
17
|
+
enterpriseAccounts(first: $first, sortColumn: $sortColumn, sortOrder: $sortOrder) {
|
18
|
+
pageInfo {
|
19
|
+
hasNextPage
|
20
|
+
endCursor
|
21
|
+
}
|
22
|
+
totalCount
|
23
|
+
edges {
|
24
|
+
node {
|
25
|
+
domain
|
26
|
+
id
|
27
|
+
identityProviders {
|
28
|
+
id
|
29
|
+
service
|
30
|
+
domain
|
31
|
+
acsUrl
|
32
|
+
ssoCert
|
33
|
+
ssoUrl
|
34
|
+
status
|
35
|
+
}
|
36
|
+
name
|
37
|
+
status
|
38
|
+
}
|
26
39
|
}
|
27
|
-
name
|
28
|
-
status
|
29
40
|
}
|
30
41
|
}
|
31
42
|
GRAPHQL
|
32
43
|
|
33
44
|
response = described_class.execute(
|
34
45
|
query,
|
35
|
-
variables:
|
46
|
+
variables: { first: 2, sortOrder: 'descending', sortColumn: 'name' },
|
36
47
|
context: { scope: current_scope },
|
37
48
|
)
|
38
49
|
|
39
50
|
expect(response['errors']).to be_nil
|
40
|
-
expect(response.dig('data', 'enterpriseAccounts').count).to eq(2)
|
51
|
+
expect(response.dig('data', 'enterpriseAccounts', 'edges').count).to eq(2)
|
52
|
+
expect(response.dig('data', 'enterpriseAccounts', 'edges', 0, 'node', 'name')).to eq('C')
|
53
|
+
expect(response.dig('data', 'enterpriseAccounts', 'totalCount')).to eq(3)
|
54
|
+
expect(response.dig('data', 'enterpriseAccounts', 'pageInfo', 'hasNextPage')).to eq(true)
|
41
55
|
end
|
42
56
|
end
|
43
57
|
end
|
@@ -17,7 +17,7 @@ describe Osso::GraphQL::Schema do
|
|
17
17
|
acsUrl
|
18
18
|
ssoCert
|
19
19
|
ssoUrl
|
20
|
-
|
20
|
+
status
|
21
21
|
}
|
22
22
|
}
|
23
23
|
GRAPHQL
|
@@ -55,7 +55,7 @@ describe Osso::GraphQL::Schema do
|
|
55
55
|
|
56
56
|
describe 'for the wrong email scoped user' do
|
57
57
|
let(:current_scope) { 'bar.com' }
|
58
|
-
|
58
|
+
|
59
59
|
it 'returns Enterprise Account for domain' do
|
60
60
|
expect(subject['errors']).to_not be_empty
|
61
61
|
expect(subject.dig('data', 'enterpriseAccount')).to be_nil
|
data/spec/routes/auth_spec.rb
CHANGED
@@ -3,6 +3,31 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Osso::Auth do
|
6
|
+
describe 'get /auth/saml/:uuid' do
|
7
|
+
describe 'for an Okta SAML provider' do
|
8
|
+
let(:enterprise) { create(:enterprise_with_okta) }
|
9
|
+
let(:okta_provider) { enterprise.identity_providers.first }
|
10
|
+
it 'uses omniauth saml' do
|
11
|
+
get("/auth/saml/#{okta_provider.id}")
|
12
|
+
|
13
|
+
expect(last_response).to be_redirect
|
14
|
+
follow_redirect!
|
15
|
+
expect(last_request.url).to match("auth/saml/#{okta_provider.id}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'for an Azure SAML provider' do
|
20
|
+
let(:enterprise) { create(:enterprise_with_okta) }
|
21
|
+
let(:azure_provider) { enterprise.identity_providers.first }
|
22
|
+
it 'uses omniauth saml' do
|
23
|
+
get("/auth/saml/#{azure_provider.id}")
|
24
|
+
|
25
|
+
expect(last_response).to be_redirect
|
26
|
+
follow_redirect!
|
27
|
+
expect(last_request.url).to match("auth/saml/#{azure_provider.id}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
6
31
|
describe 'post /auth/saml/:uuid/callback' do
|
7
32
|
describe 'for an Okta SAML provider' do
|
8
33
|
let(:enterprise) { create(:enterprise_with_okta) }
|