osso 0.0.3.7 → 0.0.3.12
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 +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
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class MarkRedirectUriPrimary < 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
|
+
redirect_uri = Osso::Models::RedirectUri.find(id)
|
16
|
+
oauth_client = redirect_uri.oauth_client
|
17
|
+
|
18
|
+
oauth_client.redirect_uris.update(primary: false)
|
19
|
+
redirect_uri.update(primary: true)
|
20
|
+
|
21
|
+
response_data(oauth_client: oauth_client.reload)
|
22
|
+
rescue StandardError => e
|
23
|
+
response_error(errors: e.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def ready?(*)
|
27
|
+
return true if context[:scope] == :admin
|
28
|
+
|
29
|
+
raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Osso
|
4
|
+
module GraphQL
|
5
|
+
module Mutations
|
6
|
+
class RegenerateOauthCredentials < BaseMutation
|
7
|
+
null false
|
8
|
+
|
9
|
+
argument :id, ID, required: true
|
10
|
+
|
11
|
+
field :oauth_client, Types::OauthClient, null: false
|
12
|
+
field :errors, [String], null: false
|
13
|
+
|
14
|
+
def resolve(id:)
|
15
|
+
oauth_client = Osso::Models::OauthClient.find(id)
|
16
|
+
oauth_client.generate_secrets
|
17
|
+
|
18
|
+
return response_data(oauth_client: oauth_client) if oauth_client.save
|
19
|
+
|
20
|
+
response_error(errors: oauth_client.errors.full_messages)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ready?(*)
|
24
|
+
return true if context[:scope] == :admin
|
25
|
+
|
26
|
+
raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/osso/graphql/query.rb
CHANGED
@@ -4,13 +4,17 @@ module Osso
|
|
4
4
|
module GraphQL
|
5
5
|
module Types
|
6
6
|
class QueryType < ::GraphQL::Schema::Object
|
7
|
-
field :enterprise_accounts, null: true, resolver: Resolvers::EnterpriseAccounts
|
8
|
-
|
7
|
+
field :enterprise_accounts, null: true, resolver: Resolvers::EnterpriseAccounts do
|
8
|
+
argument :sort_column, String, required: false
|
9
|
+
argument :sort_order, String, required: false
|
10
|
+
end
|
9
11
|
|
10
12
|
field :enterprise_account, null: true, resolver: Resolvers::EnterpriseAccount do
|
11
13
|
argument :domain, String, required: true
|
12
14
|
end
|
13
15
|
|
16
|
+
field :oauth_clients, null: true, resolver: Resolvers::OAuthClients
|
17
|
+
|
14
18
|
field(
|
15
19
|
:identity_provider,
|
16
20
|
Types::IdentityProvider,
|
@@ -19,6 +23,15 @@ module Osso
|
|
19
23
|
) do
|
20
24
|
argument :id, ID, required: true
|
21
25
|
end
|
26
|
+
|
27
|
+
field(
|
28
|
+
:oauth_client,
|
29
|
+
Types::OauthClient,
|
30
|
+
null: true,
|
31
|
+
resolve: ->(_obj, args, _context) { Osso::Models::OauthClient.find(args[:id]) },
|
32
|
+
) do
|
33
|
+
argument :id, ID, required: true
|
34
|
+
end
|
22
35
|
end
|
23
36
|
end
|
24
37
|
end
|
@@ -4,12 +4,20 @@ module Osso
|
|
4
4
|
module GraphQL
|
5
5
|
module Resolvers
|
6
6
|
class EnterpriseAccounts < ::GraphQL::Schema::Resolver
|
7
|
-
type
|
7
|
+
type Types::EnterpriseAccount.connection_type, null: true
|
8
8
|
|
9
|
-
def resolve
|
10
|
-
return Osso::Models::EnterpriseAccount.
|
9
|
+
def resolve(sort_column: nil, sort_order: nil)
|
10
|
+
return Array(Osso::Models::EnterpriseAccount.find_by(domain: context[:scope])) if context[:scope] != :admin
|
11
11
|
|
12
|
-
|
12
|
+
accounts = Osso::Models::EnterpriseAccount
|
13
|
+
|
14
|
+
accounts = accounts.order(sort_column => sort_order_sym(sort_order)) if sort_column && sort_order
|
15
|
+
|
16
|
+
accounts.all
|
17
|
+
end
|
18
|
+
|
19
|
+
def sort_order_sym(order_string)
|
20
|
+
order_string == 'ascend' ? :asc : :desc
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
data/lib/osso/graphql/types.rb
CHANGED
@@ -5,11 +5,14 @@ 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'
|
16
|
+
require_relative 'types/redirect_uri'
|
14
17
|
require_relative 'types/oauth_client'
|
15
18
|
require_relative 'types/user'
|
@@ -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,13 +17,9 @@ 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
21
|
field :documentation_pdf_url, String, null: true
|
22
22
|
|
23
|
-
def configured
|
24
|
-
!!(@object.sso_url && @object.sso_cert)
|
25
|
-
end
|
26
|
-
|
27
23
|
def documentation_pdf_url
|
28
24
|
ENV['BASE_URL'] + '/identity_provider/documentation/' + @object.id
|
29
25
|
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,19 @@ 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
|
+
field :redirect_uris, [Types::RedirectUri], null: true
|
18
|
+
|
19
|
+
def client_id
|
20
|
+
object.identifier
|
21
|
+
end
|
22
|
+
|
23
|
+
def client_secret
|
24
|
+
object.secret
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.authorized?(object, context)
|
28
|
+
super && context[:scope] == :admin
|
29
|
+
end
|
17
30
|
end
|
18
31
|
end
|
19
32
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql'
|
4
|
+
|
5
|
+
module Osso
|
6
|
+
module GraphQL
|
7
|
+
module Types
|
8
|
+
class RedirectUri < Types::BaseObject
|
9
|
+
description 'An allowed redirect URI for an OauthClient'
|
10
|
+
implements ::GraphQL::Types::Relay::Node
|
11
|
+
|
12
|
+
global_id_field :gid
|
13
|
+
field :id, ID, null: false
|
14
|
+
field :uri, String, null: false
|
15
|
+
field :primary, Boolean, null: false
|
16
|
+
|
17
|
+
def self.authorized?(object, context)
|
18
|
+
super && context[:scope] == :admin
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/osso/helpers/auth.rb
CHANGED
@@ -14,13 +14,10 @@ module Osso
|
|
14
14
|
redirect ENV['JWT_URL']
|
15
15
|
end
|
16
16
|
|
17
|
+
# use client id in payload to restrict customer
|
18
|
+
# users from accessing dev?
|
17
19
|
def enterprise_authorized?(_domain)
|
18
|
-
payload, _args =
|
19
|
-
token,
|
20
|
-
ENV['JWT_HMAC_SECRET'],
|
21
|
-
true,
|
22
|
-
{ algorithm: 'HS256' },
|
23
|
-
)
|
20
|
+
payload, _args = decode(token)
|
24
21
|
|
25
22
|
@current_scope = payload['scope']
|
26
23
|
|
@@ -36,12 +33,7 @@ module Osso
|
|
36
33
|
end
|
37
34
|
|
38
35
|
def admin_authorized?
|
39
|
-
payload, _args =
|
40
|
-
token,
|
41
|
-
ENV['JWT_HMAC_SECRET'],
|
42
|
-
true,
|
43
|
-
{ algorithm: 'HS256' },
|
44
|
-
)
|
36
|
+
payload, _args = decode(token)
|
45
37
|
|
46
38
|
if payload['scope'] == 'admin'
|
47
39
|
@current_scope = :admin
|
@@ -66,6 +58,15 @@ module Osso
|
|
66
58
|
|
67
59
|
redirect request.path
|
68
60
|
end
|
61
|
+
|
62
|
+
def decode(token)
|
63
|
+
JWT.decode(
|
64
|
+
token,
|
65
|
+
ENV['JWT_HMAC_SECRET'],
|
66
|
+
true,
|
67
|
+
{ algorithm: 'HS256' },
|
68
|
+
)
|
69
|
+
end
|
69
70
|
end
|
70
71
|
end
|
71
72
|
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
@@ -9,24 +9,34 @@ module Osso
|
|
9
9
|
has_many :identity_providers
|
10
10
|
has_many :redirect_uris
|
11
11
|
|
12
|
-
before_validation :
|
12
|
+
before_validation :generate_secrets, on: :create
|
13
13
|
validates :name, :secret, presence: true
|
14
14
|
validates :identifier, presence: true, uniqueness: true
|
15
15
|
|
16
|
-
def
|
16
|
+
def primary_redirect_uri
|
17
17
|
redirect_uris.find(&:primary)
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
redirect_uris.map(&:uri)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def setup
|
20
|
+
def generate_secrets
|
27
21
|
self.identifier = SecureRandom.hex(16)
|
28
|
-
self.secret = SecureRandom.hex(
|
22
|
+
self.secret = SecureRandom.hex(32)
|
29
23
|
end
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
27
|
+
|
28
|
+
# == Schema Information
|
29
|
+
#
|
30
|
+
# Table name: oauth_clients
|
31
|
+
#
|
32
|
+
# id :uuid not null, primary key
|
33
|
+
# name :string not null
|
34
|
+
# secret :string not null
|
35
|
+
# identifier :string not null
|
36
|
+
# created_at :datetime not null
|
37
|
+
# updated_at :datetime not null
|
38
|
+
#
|
39
|
+
# Indexes
|
40
|
+
#
|
41
|
+
# index_oauth_clients_on_identifier (identifier) UNIQUE
|
42
|
+
#
|