osso 0.0.3.6 → 0.0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- 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 +4 -2
- data/lib/osso/graphql/mutations.rb +3 -1
- data/lib/osso/graphql/mutations/base_mutation.rb +8 -2
- data/lib/osso/graphql/mutations/configure_identity_provider.rb +10 -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/query.rb +4 -1
- data/lib/osso/graphql/resolvers/enterprise_accounts.rb +12 -4
- data/lib/osso/graphql/resolvers/oauth_clients.rb +1 -1
- data/lib/osso/graphql/schema.rb +4 -0
- data/lib/osso/graphql/types.rb +2 -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/enterprise_account.rb +4 -0
- data/lib/osso/graphql/types/identity_provider.rb +8 -3
- data/lib/osso/graphql/types/identity_provider_status.rb +14 -0
- data/lib/osso/graphql/types/oauth_client.rb +13 -1
- data/lib/osso/helpers/auth.rb +11 -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 +17 -1
- data/lib/osso/models/redirect_uri.rb +17 -0
- data/lib/osso/models/user.rb +22 -0
- 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 +14 -4
- 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 +9 -6
- data/spec/graphql/query/{oauth_clients_account_spec.rb → oauth_clients_spec.rb} +2 -0
- metadata +30 -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
data/lib/osso/graphql/schema.rb
CHANGED
data/lib/osso/graphql/types.rb
CHANGED
@@ -5,10 +5,12 @@ module Osso
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
+
require_relative 'types/base_connection'
|
8
9
|
require_relative 'types/base_object'
|
9
10
|
require_relative 'types/base_enum'
|
10
11
|
require_relative 'types/base_input_object'
|
11
12
|
require_relative 'types/identity_provider_service'
|
13
|
+
require_relative 'types/identity_provider_status'
|
12
14
|
require_relative 'types/identity_provider'
|
13
15
|
require_relative 'types/enterprise_account'
|
14
16
|
require_relative 'types/oauth_client'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Types
|
6
|
+
class BaseConnection < ::GraphQL::Types::Relay::BaseConnection
|
7
|
+
field :total_count, Integer, null: false
|
8
|
+
|
9
|
+
def total_count
|
10
|
+
object.items&.count
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -6,6 +6,10 @@ module Osso
|
|
6
6
|
module GraphQL
|
7
7
|
module Types
|
8
8
|
class BaseObject < ::GraphQL::Schema::Object
|
9
|
+
connection_type_class GraphQL::Types::BaseConnection
|
10
|
+
|
11
|
+
field :created_at, ::GraphQL::Types::ISO8601DateTime, null: false
|
12
|
+
field :updated_at, ::GraphQL::Types::ISO8601DateTime, null: false
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -17,10 +17,15 @@ module Osso
|
|
17
17
|
field :acs_url, String, null: false
|
18
18
|
field :sso_url, String, null: true
|
19
19
|
field :sso_cert, String, null: true
|
20
|
-
field :
|
20
|
+
field :status, Types::IdentityProviderStatus, null: false
|
21
|
+
field :documentation_pdf_url, String, null: true
|
21
22
|
|
22
|
-
def
|
23
|
-
|
23
|
+
def documentation_pdf_url
|
24
|
+
ENV['BASE_URL'] + '/identity_provider/documentation/' + @object.id
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.authorized?(object, context)
|
28
|
+
super && (context[:scope] == :admin || object.domain == context[:scope])
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Types
|
6
|
+
class IdentityProviderStatus < BaseEnum
|
7
|
+
value('Pending', value: 'PENDING')
|
8
|
+
value('Configured', value: 'CONFIGURED')
|
9
|
+
value('Active', value: 'ACTIVE')
|
10
|
+
value('Error', value: 'ERROR')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -5,7 +5,7 @@ require 'graphql'
|
|
5
5
|
module Osso
|
6
6
|
module GraphQL
|
7
7
|
module Types
|
8
|
-
class
|
8
|
+
class OauthClient < Types::BaseObject
|
9
9
|
description 'An OAuth client used to consume Osso SAML users'
|
10
10
|
implements ::GraphQL::Types::Relay::Node
|
11
11
|
|
@@ -14,6 +14,18 @@ module Osso
|
|
14
14
|
field :name, String, null: false
|
15
15
|
field :client_id, String, null: false
|
16
16
|
field :client_secret, String, null: false
|
17
|
+
|
18
|
+
def client_id
|
19
|
+
object.identifier
|
20
|
+
end
|
21
|
+
|
22
|
+
def client_secret
|
23
|
+
object.secret
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.authorized?(object, context)
|
27
|
+
super && context[:scope] == :admin
|
28
|
+
end
|
17
29
|
end
|
18
30
|
end
|
19
31
|
end
|
data/lib/osso/helpers/auth.rb
CHANGED
@@ -15,12 +15,7 @@ module Osso
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def enterprise_authorized?(_domain)
|
18
|
-
payload, _args =
|
19
|
-
token,
|
20
|
-
ENV['JWT_HMAC_SECRET'],
|
21
|
-
true,
|
22
|
-
{ algorithm: 'HS256' },
|
23
|
-
)
|
18
|
+
payload, _args = decode(token)
|
24
19
|
|
25
20
|
@current_scope = payload['scope']
|
26
21
|
|
@@ -36,12 +31,7 @@ module Osso
|
|
36
31
|
end
|
37
32
|
|
38
33
|
def admin_authorized?
|
39
|
-
payload, _args =
|
40
|
-
token,
|
41
|
-
ENV['JWT_HMAC_SECRET'],
|
42
|
-
true,
|
43
|
-
{ algorithm: 'HS256' },
|
44
|
-
)
|
34
|
+
payload, _args = decode(token)
|
45
35
|
|
46
36
|
if payload['scope'] == 'admin'
|
47
37
|
@current_scope = :admin
|
@@ -66,6 +56,15 @@ module Osso
|
|
66
56
|
|
67
57
|
redirect request.path
|
68
58
|
end
|
59
|
+
|
60
|
+
def decode(token)
|
61
|
+
JWT.decode(
|
62
|
+
token,
|
63
|
+
ENV['JWT_HMAC_SECRET'],
|
64
|
+
true,
|
65
|
+
{ algorithm: 'HS256' },
|
66
|
+
)
|
67
|
+
end
|
69
68
|
end
|
70
69
|
end
|
71
70
|
end
|
@@ -27,3 +27,21 @@ module Osso
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
# == Schema Information
|
32
|
+
#
|
33
|
+
# Table name: access_tokens
|
34
|
+
#
|
35
|
+
# id :uuid not null, primary key
|
36
|
+
# token :string
|
37
|
+
# expires_at :datetime
|
38
|
+
# created_at :datetime not null
|
39
|
+
# updated_at :datetime not null
|
40
|
+
# user_id :uuid
|
41
|
+
# oauth_client_id :uuid
|
42
|
+
#
|
43
|
+
# Indexes
|
44
|
+
#
|
45
|
+
# index_access_tokens_on_oauth_client_id (oauth_client_id)
|
46
|
+
# index_access_tokens_on_user_id (user_id)
|
47
|
+
#
|
@@ -12,3 +12,23 @@ module Osso
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
# == Schema Information
|
17
|
+
#
|
18
|
+
# Table name: authorization_codes
|
19
|
+
#
|
20
|
+
# id :uuid not null, primary key
|
21
|
+
# token :string
|
22
|
+
# redirect_uri :string
|
23
|
+
# expires_at :datetime
|
24
|
+
# created_at :datetime not null
|
25
|
+
# updated_at :datetime not null
|
26
|
+
# user_id :uuid
|
27
|
+
# oauth_client_id :uuid
|
28
|
+
#
|
29
|
+
# Indexes
|
30
|
+
#
|
31
|
+
# index_authorization_codes_on_oauth_client_id (oauth_client_id)
|
32
|
+
# index_authorization_codes_on_token (token) UNIQUE
|
33
|
+
# index_authorization_codes_on_user_id (user_id)
|
34
|
+
#
|
@@ -26,3 +26,23 @@ module Osso
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
# == Schema Information
|
31
|
+
#
|
32
|
+
# Table name: enterprise_accounts
|
33
|
+
#
|
34
|
+
# id :uuid not null, primary key
|
35
|
+
# domain :string not null
|
36
|
+
# external_uuid :uuid
|
37
|
+
# external_int_id :integer
|
38
|
+
# external_id :string
|
39
|
+
# oauth_client_id :uuid
|
40
|
+
# name :string not null
|
41
|
+
# created_at :datetime not null
|
42
|
+
# updated_at :datetime not null
|
43
|
+
#
|
44
|
+
# Indexes
|
45
|
+
#
|
46
|
+
# index_enterprise_accounts_on_domain (domain) UNIQUE
|
47
|
+
# index_enterprise_accounts_on_oauth_client_id (oauth_client_id)
|
48
|
+
#
|
@@ -8,6 +8,7 @@ module Osso
|
|
8
8
|
belongs_to :enterprise_account
|
9
9
|
belongs_to :oauth_client
|
10
10
|
has_many :users
|
11
|
+
before_save :set_status
|
11
12
|
|
12
13
|
def name
|
13
14
|
service.titlecase
|
@@ -43,6 +44,34 @@ module Osso
|
|
43
44
|
end
|
44
45
|
|
45
46
|
alias acs_url assertion_consumer_service_url
|
47
|
+
|
48
|
+
def set_status
|
49
|
+
return if status != 'PENDING'
|
50
|
+
|
51
|
+
self.status = 'CONFIGURED' if sso_url && sso_cert
|
52
|
+
end
|
46
53
|
end
|
47
54
|
end
|
48
55
|
end
|
56
|
+
|
57
|
+
# == Schema Information
|
58
|
+
#
|
59
|
+
# Table name: identity_providers
|
60
|
+
#
|
61
|
+
# id :uuid not null, primary key
|
62
|
+
# service :string
|
63
|
+
# domain :string not null
|
64
|
+
# sso_url :string
|
65
|
+
# sso_cert :text
|
66
|
+
# enterprise_account_id :uuid
|
67
|
+
# oauth_client_id :uuid
|
68
|
+
# status :enum default("PENDING")
|
69
|
+
# created_at :datetime
|
70
|
+
# updated_at :datetime
|
71
|
+
#
|
72
|
+
# Indexes
|
73
|
+
#
|
74
|
+
# index_identity_providers_on_domain (domain)
|
75
|
+
# index_identity_providers_on_enterprise_account_id (enterprise_account_id)
|
76
|
+
# index_identity_providers_on_oauth_client_id (oauth_client_id)
|
77
|
+
#
|
data/lib/osso/models/models.rb
CHANGED
@@ -25,8 +25,24 @@ module Osso
|
|
25
25
|
|
26
26
|
def setup
|
27
27
|
self.identifier = SecureRandom.hex(16)
|
28
|
-
self.secret = SecureRandom.hex(
|
28
|
+
self.secret = SecureRandom.hex(32)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
# == Schema Information
|
35
|
+
#
|
36
|
+
# Table name: oauth_clients
|
37
|
+
#
|
38
|
+
# id :uuid not null, primary key
|
39
|
+
# name :string not null
|
40
|
+
# secret :string not null
|
41
|
+
# identifier :string not null
|
42
|
+
# created_at :datetime not null
|
43
|
+
# updated_at :datetime not null
|
44
|
+
#
|
45
|
+
# Indexes
|
46
|
+
#
|
47
|
+
# index_oauth_clients_on_identifier (identifier) UNIQUE
|
48
|
+
#
|
@@ -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/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
|
|
@@ -55,11 +55,21 @@ describe Osso::GraphQL::Schema do
|
|
55
55
|
let(:domain) { Faker::Internet.domain_name }
|
56
56
|
let(:current_scope) { domain }
|
57
57
|
let(:enterprise_account) { create(:enterprise_account, domain: domain) }
|
58
|
+
let(:identity_provider) { create(:identity_provider, enterprise_account: enterprise_account, domain: domain) }
|
58
59
|
|
59
|
-
it '
|
60
|
+
it 'configures an identity provider' do
|
60
61
|
expect(subject.dig('data', 'configureIdentityProvider', 'identityProvider', 'domain')).
|
61
62
|
to eq(domain)
|
62
63
|
end
|
63
64
|
end
|
65
|
+
|
66
|
+
describe 'for the wrong email scoped user' do
|
67
|
+
let(:domain) { Faker::Internet.domain_name }
|
68
|
+
let(:current_scope) { domain }
|
69
|
+
|
70
|
+
it 'does not configure an identity provider' do
|
71
|
+
expect(subject.dig('errors')).to_not be_empty
|
72
|
+
end
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|