osso 0.0.3.4 → 0.0.3.9
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 +6 -1
- data/.rubocop.yml +1 -2
- data/Gemfile.lock +5 -1
- data/bin/annotate +1 -0
- data/bin/console +4 -3
- data/config/database.yml +2 -2
- data/db/schema.rb +90 -1
- data/lib/osso.rb +1 -0
- data/lib/osso/db/migrate/20200328143305_create_identity_providers.rb +12 -0
- data/lib/osso/db/migrate/20200411184535_add_provider_id_to_users.rb +2 -2
- data/lib/osso/db/migrate/20200411192645_create_enterprise_accounts.rb +1 -1
- data/lib/osso/db/migrate/20200502135008_add_oauth_client_id_to_enterprise_accounts_and_identity_providers.rb +6 -0
- data/lib/osso/db/migrate/20200714223226_add_identity_provider_service_enum.rb +17 -0
- data/lib/osso/db/migrate/20200715154211_rename_idp_fields_on_identity_provider_to_sso.rb +6 -0
- data/lib/osso/db/migrate/20200715205801_add_name_to_enterprise_account.rb +5 -0
- 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 +5 -2
- data/lib/osso/graphql/mutations.rb +5 -1
- data/lib/osso/graphql/mutations/base_mutation.rb +24 -7
- data/lib/osso/graphql/mutations/configure_identity_provider.rb +19 -13
- data/lib/osso/graphql/mutations/create_enterprise_account.rb +25 -0
- data/lib/osso/graphql/mutations/create_identity_provider.rb +9 -7
- 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 +2 -2
- data/lib/osso/graphql/resolvers/oauth_clients.rb +2 -2
- data/lib/osso/graphql/schema.rb +5 -1
- data/lib/osso/graphql/types.rb +2 -0
- data/lib/osso/graphql/types/base_input_object.rb +10 -0
- data/lib/osso/graphql/types/base_object.rb +2 -0
- data/lib/osso/graphql/types/enterprise_account.rb +5 -5
- data/lib/osso/graphql/types/identity_provider.rb +6 -13
- data/lib/osso/graphql/types/identity_provider_service.rb +1 -1
- 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 +16 -15
- data/lib/osso/lib/app_config.rb +1 -1
- data/lib/osso/lib/route_map.rb +28 -0
- 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 +24 -4
- data/lib/osso/models/identity_provider.rb +77 -0
- data/lib/osso/models/models.rb +3 -1
- data/lib/osso/models/oauth_client.rb +19 -3
- data/lib/osso/models/redirect_uri.rb +17 -0
- data/lib/osso/models/user.rb +25 -3
- data/lib/osso/routes/admin.rb +18 -15
- data/lib/osso/routes/auth.rb +30 -27
- data/lib/osso/routes/oauth.rb +50 -45
- data/lib/osso/version.rb +1 -1
- data/osso-rb.gemspec +3 -3
- data/spec/factories/enterprise_account.rb +5 -4
- data/spec/factories/identity_providers.rb +71 -0
- data/spec/factories/user.rb +1 -1
- data/spec/graphql/mutations/configure_identity_provider_spec.rb +75 -0
- data/spec/graphql/mutations/create_enterprise_account_spec.rb +68 -0
- data/spec/graphql/mutations/create_identity_provider_spec.rb +104 -0
- 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 +68 -0
- data/spec/graphql/query/enterprise_accounts_spec.rb +44 -0
- data/spec/graphql/query/identity_provider_spec.rb +65 -0
- data/spec/graphql/query/oauth_clients_spec.rb +50 -0
- data/spec/models/azure_saml_provider_spec.rb +14 -14
- data/spec/models/identity_provider_spec.rb +17 -0
- data/spec/models/okta_saml_provider_spec.rb +15 -15
- data/spec/routes/admin_spec.rb +2 -0
- data/spec/routes/auth_spec.rb +9 -9
- data/spec/routes/oauth_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -5
- data/spec/support/spec_app.rb +9 -0
- metadata +47 -16
- data/lib/osso/db/migrate/20200328143303_create_oauth_tables.rb +0 -57
- data/lib/osso/db/migrate/20200411144528_create_saml_providers.rb +0 -13
- data/lib/osso/db/migrate/20200413153029_add_oauth_client_reference_to_saml_providers.rb +0 -5
- data/lib/osso/db/migrate/20200501203026_drop_null_constraints_from_saml_provider.rb +0 -7
- data/lib/osso/db/migrate/20200501204047_drop_acs_url.rb +0 -5
- data/lib/osso/db/migrate/20200502135008_add_oauth_client_id_to_enterprise_account.rb +0 -5
- data/lib/osso/db/migrate/20200601131227_drop_null_constraint_from_saml_providers_provider.rb +0 -7
- data/lib/osso/db/schema.rb +0 -132
- data/lib/osso/graphql/mutations/set_saml_provider.rb +0 -27
- data/lib/osso/models/saml_provider.rb +0 -52
- 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/spec/factories/saml_providers.rb +0 -46
- data/spec/models/saml_provider_spec.rb +0 -31
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class CreateEnterpriseAccount < BaseMutation
|
7
|
+
null false
|
8
|
+
|
9
|
+
argument :domain, String, required: true
|
10
|
+
argument :name, String, required: true
|
11
|
+
|
12
|
+
field :enterprise_account, Types::EnterpriseAccount, null: false
|
13
|
+
field :errors, [String], null: false
|
14
|
+
|
15
|
+
def resolve(**args)
|
16
|
+
enterprise_account = Osso::Models::EnterpriseAccount.new(args)
|
17
|
+
|
18
|
+
return response_data(enterprise_account: enterprise_account) if enterprise_account.save
|
19
|
+
|
20
|
+
response_error(errors: enterprise_account.errors.full_messages)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -5,22 +5,24 @@ module Osso
|
|
5
5
|
module Mutations
|
6
6
|
class CreateIdentityProvider < BaseMutation
|
7
7
|
null false
|
8
|
+
|
8
9
|
argument :enterprise_account_id, ID, required: true
|
9
|
-
argument :
|
10
|
+
argument :service, Types::IdentityProviderService, required: false
|
10
11
|
|
11
12
|
field :identity_provider, Types::IdentityProvider, null: false
|
12
13
|
field :errors, [String], null: false
|
13
14
|
|
14
|
-
def resolve(enterprise_account_id:,
|
15
|
+
def resolve(enterprise_account_id:, service: nil)
|
15
16
|
enterprise_account = Osso::Models::EnterpriseAccount.find(enterprise_account_id)
|
16
|
-
identity_provider = enterprise_account.
|
17
|
-
|
17
|
+
identity_provider = enterprise_account.identity_providers.build(
|
18
|
+
enterprise_account_id: enterprise_account_id,
|
19
|
+
service: service,
|
18
20
|
domain: enterprise_account.domain,
|
19
21
|
)
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
return response_data(identity_provider: identity_provider) if identity_provider.save
|
24
|
+
|
25
|
+
response_error(errors: identity_provider.errors.full_messages)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class CreateOauthClient < BaseMutation
|
7
|
+
null false
|
8
|
+
|
9
|
+
argument :name, String, required: true
|
10
|
+
|
11
|
+
field :oauth_client, Types::OauthClient, null: false
|
12
|
+
field :errors, [String], null: false
|
13
|
+
|
14
|
+
def resolve(**args)
|
15
|
+
oauth_client = Osso::Models::OauthClient.new(args)
|
16
|
+
|
17
|
+
return response_data(oauth_client: oauth_client) if oauth_client.save
|
18
|
+
|
19
|
+
response_error(errors: oauth_client.errors.full_messages)
|
20
|
+
end
|
21
|
+
|
22
|
+
def ready?(*)
|
23
|
+
return true if context[:scope] == :admin
|
24
|
+
|
25
|
+
raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class DeleteEnterpriseAccount < BaseMutation
|
7
|
+
null false
|
8
|
+
|
9
|
+
argument :id, ID, required: true
|
10
|
+
|
11
|
+
field :enterprise_account, Types::EnterpriseAccount, null: true
|
12
|
+
field :errors, [String], null: false
|
13
|
+
|
14
|
+
def resolve(id:)
|
15
|
+
enterprise_account = Osso::Models::EnterpriseAccount.find(id)
|
16
|
+
|
17
|
+
return response_data(enterprise_account: nil) if enterprise_account.destroy
|
18
|
+
|
19
|
+
response_error(errors: enterprise_account.errors.full_messages)
|
20
|
+
end
|
21
|
+
|
22
|
+
def ready?(id:)
|
23
|
+
return true if context[:scope] == :admin
|
24
|
+
|
25
|
+
domain = account_domain(id)
|
26
|
+
|
27
|
+
return true if domain == context[:scope]
|
28
|
+
|
29
|
+
raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{domain}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class DeleteOauthClient < BaseMutation
|
7
|
+
null false
|
8
|
+
|
9
|
+
argument :id, ID, required: true
|
10
|
+
|
11
|
+
field :oauth_client, Types::OauthClient, null: true
|
12
|
+
field :errors, [String], null: false
|
13
|
+
|
14
|
+
def resolve(id:)
|
15
|
+
oauth_client = Osso::Models::OauthClient.find(id)
|
16
|
+
|
17
|
+
return response_data(oauth_client: nil) if oauth_client.destroy
|
18
|
+
|
19
|
+
response_error(errors: oauth_client.errors.full_messages)
|
20
|
+
end
|
21
|
+
|
22
|
+
def ready?(*)
|
23
|
+
return true if context[:scope] == :admin
|
24
|
+
|
25
|
+
raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/osso/graphql/query.rb
CHANGED
@@ -7,7 +7,7 @@ module Osso
|
|
7
7
|
field :enterprise_accounts, null: true, resolver: Resolvers::EnterpriseAccounts
|
8
8
|
field :oauth_clients, null: true, resolver: Resolvers::OAuthClients
|
9
9
|
|
10
|
-
field :enterprise_account, null:
|
10
|
+
field :enterprise_account, null: true, resolver: Resolvers::EnterpriseAccount do
|
11
11
|
argument :domain, String, required: true
|
12
12
|
end
|
13
13
|
|
@@ -15,7 +15,7 @@ module Osso
|
|
15
15
|
:identity_provider,
|
16
16
|
Types::IdentityProvider,
|
17
17
|
null: true,
|
18
|
-
resolve: ->(_obj, args, _context) { Osso::Models::
|
18
|
+
resolve: ->(_obj, args, _context) { Osso::Models::IdentityProvider.find(args[:id]) },
|
19
19
|
) do
|
20
20
|
argument :id, ID, required: true
|
21
21
|
end
|
@@ -4,10 +4,10 @@ module Osso
|
|
4
4
|
module GraphQL
|
5
5
|
module Resolvers
|
6
6
|
class OAuthClients < ::GraphQL::Schema::Resolver
|
7
|
-
type [Types::
|
7
|
+
type [Types::OauthClient], null: true
|
8
8
|
|
9
9
|
def resolve
|
10
|
-
return Osso::Models::
|
10
|
+
return Osso::Models::OauthClient.all if context[:scope] == :admin
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/lib/osso/graphql/schema.rb
CHANGED
@@ -31,12 +31,16 @@ module Osso
|
|
31
31
|
case obj
|
32
32
|
when Osso::Models::EnterpriseAccount
|
33
33
|
Types::EnterpriseAccount
|
34
|
-
when Osso::Models::
|
34
|
+
when Osso::Models::IdentityProvider
|
35
35
|
Types::IdentityProvider
|
36
36
|
else
|
37
37
|
raise("Unexpected object: #{obj}")
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def self.unauthorized_object(error)
|
42
|
+
raise ::GraphQL::ExecutionError, "An object of type #{error.type.graphql_name} was hidden due to permissions"
|
43
|
+
end
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
data/lib/osso/graphql/types.rb
CHANGED
@@ -7,7 +7,9 @@ end
|
|
7
7
|
|
8
8
|
require_relative 'types/base_object'
|
9
9
|
require_relative 'types/base_enum'
|
10
|
+
require_relative 'types/base_input_object'
|
10
11
|
require_relative 'types/identity_provider_service'
|
12
|
+
require_relative 'types/identity_provider_status'
|
11
13
|
require_relative 'types/identity_provider'
|
12
14
|
require_relative 'types/enterprise_account'
|
13
15
|
require_relative 'types/oauth_client'
|
@@ -16,16 +16,16 @@ module Osso
|
|
16
16
|
field :identity_providers, [Types::IdentityProvider], null: true
|
17
17
|
field :status, String, null: false
|
18
18
|
|
19
|
-
def name
|
20
|
-
object.domain.gsub('.com', '')
|
21
|
-
end
|
22
|
-
|
23
19
|
def status
|
24
20
|
'active'
|
25
21
|
end
|
26
22
|
|
27
23
|
def identity_providers
|
28
|
-
object.
|
24
|
+
object.identity_providers
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.authorized?(object, context)
|
28
|
+
super && (context[:scope] == :admin || object.domain == context[:scope])
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -17,22 +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
|
-
@object.
|
23
|
+
def documentation_pdf_url
|
24
|
+
ENV['BASE_URL'] + '/identity_provider/documentation/' + @object.id
|
24
25
|
end
|
25
26
|
|
26
|
-
def
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
def sso_cert
|
31
|
-
@object.idp_cert
|
32
|
-
end
|
33
|
-
|
34
|
-
def sso_url
|
35
|
-
@object.idp_sso_target_url
|
27
|
+
def self.authorized?(object, context)
|
28
|
+
super && (context[:scope] == :admin || object.domain == context[:scope])
|
36
29
|
end
|
37
30
|
end
|
38
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
@@ -4,21 +4,18 @@ module Osso
|
|
4
4
|
module Helpers
|
5
5
|
module Auth
|
6
6
|
attr_accessor :current_scope
|
7
|
-
|
7
|
+
|
8
8
|
def enterprise_protected!(domain = nil)
|
9
9
|
return if admin_authorized?
|
10
10
|
return if enterprise_authorized?(domain)
|
11
11
|
|
12
|
+
halt 401 if request.post?
|
13
|
+
|
12
14
|
redirect ENV['JWT_URL']
|
13
15
|
end
|
14
16
|
|
15
|
-
def enterprise_authorized?(
|
16
|
-
payload, _args =
|
17
|
-
token,
|
18
|
-
ENV['JWT_HMAC_SECRET'],
|
19
|
-
true,
|
20
|
-
{ algorithm: 'HS256' },
|
21
|
-
)
|
17
|
+
def enterprise_authorized?(_domain)
|
18
|
+
payload, _args = decode(token)
|
22
19
|
|
23
20
|
@current_scope = payload['scope']
|
24
21
|
|
@@ -34,12 +31,7 @@ module Osso
|
|
34
31
|
end
|
35
32
|
|
36
33
|
def admin_authorized?
|
37
|
-
payload, _args =
|
38
|
-
token,
|
39
|
-
ENV['JWT_HMAC_SECRET'],
|
40
|
-
true,
|
41
|
-
{ algorithm: 'HS256' },
|
42
|
-
)
|
34
|
+
payload, _args = decode(token)
|
43
35
|
|
44
36
|
if payload['scope'] == 'admin'
|
45
37
|
@current_scope = :admin
|
@@ -64,6 +56,15 @@ module Osso
|
|
64
56
|
|
65
57
|
redirect request.path
|
66
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
|
67
68
|
end
|
68
69
|
end
|
69
|
-
end
|
70
|
+
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['SESSION_SECRET']
|
11
11
|
|
12
12
|
error ActiveRecord::RecordNotFound do
|
13
13
|
status 404
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/MethodLength
|
4
|
+
|
5
|
+
module Osso
|
6
|
+
module RouteMap
|
7
|
+
def self.included(klass)
|
8
|
+
klass.class_eval do
|
9
|
+
use Osso::Admin
|
10
|
+
use Osso::Auth
|
11
|
+
use Osso::Oauth
|
12
|
+
|
13
|
+
post '/graphql' do
|
14
|
+
enterprise_protected!
|
15
|
+
|
16
|
+
result = Osso::GraphQL::Schema.execute(
|
17
|
+
params[:query],
|
18
|
+
variables: params[:variables],
|
19
|
+
context: { scope: current_scope },
|
20
|
+
)
|
21
|
+
|
22
|
+
json result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
# rubocop:enable Metrics/MethodLength
|
@@ -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
|
+
#
|