osso 0.0.3.8 → 0.0.3.13

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.yml +5 -3
  3. data/Gemfile.lock +5 -1
  4. data/bin/annotate +1 -0
  5. data/db/schema.rb +9 -43
  6. data/lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb +35 -0
  7. data/lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb +9 -0
  8. data/lib/osso/graphql/mutation.rb +7 -1
  9. data/lib/osso/graphql/mutations.rb +5 -1
  10. data/lib/osso/graphql/mutations/configure_identity_provider.rb +1 -1
  11. data/lib/osso/graphql/mutations/create_oauth_client.rb +30 -0
  12. data/lib/osso/graphql/mutations/delete_enterprise_account.rb +34 -0
  13. data/lib/osso/graphql/mutations/delete_oauth_client.rb +30 -0
  14. data/lib/osso/graphql/mutations/regenerate_oauth_credentials.rb +31 -0
  15. data/lib/osso/graphql/mutations/set_redirect_uris.rb +54 -0
  16. data/lib/osso/graphql/query.rb +15 -2
  17. data/lib/osso/graphql/resolvers/enterprise_accounts.rb +12 -4
  18. data/lib/osso/graphql/resolvers/oauth_clients.rb +1 -1
  19. data/lib/osso/graphql/types.rb +3 -0
  20. data/lib/osso/graphql/types/base_connection.rb +15 -0
  21. data/lib/osso/graphql/types/base_object.rb +4 -0
  22. data/lib/osso/graphql/types/oauth_client.rb +14 -1
  23. data/lib/osso/graphql/types/redirect_uri.rb +23 -0
  24. data/lib/osso/graphql/types/redirect_uri_input.rb +16 -0
  25. data/lib/osso/helpers/auth.rb +13 -12
  26. data/lib/osso/models/access_token.rb +18 -0
  27. data/lib/osso/models/authorization_code.rb +20 -0
  28. data/lib/osso/models/enterprise_account.rb +20 -0
  29. data/lib/osso/models/identity_provider.rb +22 -1
  30. data/lib/osso/models/models.rb +2 -0
  31. data/lib/osso/models/oauth_client.rb +20 -6
  32. data/lib/osso/models/redirect_uri.rb +17 -0
  33. data/lib/osso/models/user.rb +22 -0
  34. data/lib/osso/routes/admin.rb +6 -0
  35. data/lib/osso/routes/auth.rb +2 -2
  36. data/lib/osso/version.rb +1 -1
  37. data/osso-rb.gemspec +1 -0
  38. data/spec/factories/identity_providers.rb +22 -0
  39. data/spec/graphql/mutations/configure_identity_provider_spec.rb +1 -1
  40. data/spec/graphql/mutations/create_oauth_client_spec.rb +55 -0
  41. data/spec/graphql/mutations/delete_enterprise_account_spec.rb +63 -0
  42. data/spec/graphql/mutations/delete_oauth_client_spec.rb +51 -0
  43. data/spec/graphql/query/enterprise_accounts_spec.rb +32 -18
  44. data/spec/graphql/query/identity_provider_spec.rb +1 -1
  45. data/spec/graphql/query/{oauth_clients_account_spec.rb → oauth_clients_spec.rb} +2 -0
  46. data/spec/routes/auth_spec.rb +25 -0
  47. metadata +32 -8
  48. data/lib/osso/db/migrate/20200328143303_create_oauth_tables.rb +0 -57
  49. data/lib/osso/graphql/mutations/set_identity_provider.rb +0 -27
  50. data/lib/osso/models/saml_provider.rb +0 -49
  51. data/lib/osso/models/saml_providers/azure_saml_provider.rb +0 -22
  52. data/lib/osso/models/saml_providers/okta_saml_provider.rb +0 -23
@@ -4,12 +4,20 @@ module Osso
4
4
  module GraphQL
5
5
  module Resolvers
6
6
  class EnterpriseAccounts < ::GraphQL::Schema::Resolver
7
- type [Types::EnterpriseAccount], null: true
7
+ type Types::EnterpriseAccount.connection_type, null: true
8
8
 
9
- def resolve
10
- return Osso::Models::EnterpriseAccount.all if context[:scope] == :admin
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
- Array(Osso::Models::EnterpriseAccount.find_by(domain: context[:scope]))
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
@@ -4,7 +4,7 @@ module Osso
4
4
  module GraphQL
5
5
  module Resolvers
6
6
  class OAuthClients < ::GraphQL::Schema::Resolver
7
- type [Types::OAuthClient], null: true
7
+ type [Types::OauthClient], null: true
8
8
 
9
9
  def resolve
10
10
  return Osso::Models::OauthClient.all if context[:scope] == :admin
@@ -5,6 +5,7 @@ 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'
@@ -12,5 +13,7 @@ require_relative 'types/identity_provider_service'
12
13
  require_relative 'types/identity_provider_status'
13
14
  require_relative 'types/identity_provider'
14
15
  require_relative 'types/enterprise_account'
16
+ require_relative 'types/redirect_uri'
17
+ require_relative 'types/redirect_uri_input'
15
18
  require_relative 'types/oauth_client'
16
19
  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
@@ -5,7 +5,7 @@ require 'graphql'
5
5
  module Osso
6
6
  module GraphQL
7
7
  module Types
8
- class OAuthClient < Types::BaseObject
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
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+
5
+ module Osso
6
+ module GraphQL
7
+ module Types
8
+ class RedirectUrisInput < Types::BaseInputObject
9
+ description 'Attributes for creating or updating a collection of redirect URIs for an Oauth Client'
10
+ argument :id, ID, 'Database ID', required: false
11
+ argument :uri, String, 'URI value', required: true
12
+ argument :primary, Boolean, 'Whether the URI is the primary uri used in IDP initiated login', required: true
13
+ end
14
+ end
15
+ end
16
+ end
@@ -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 = JWT.decode(
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 = JWT.decode(
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
+ #
@@ -10,7 +10,6 @@ module Osso
10
10
  has_many :users
11
11
  before_save :set_status
12
12
 
13
-
14
13
  def name
15
14
  service.titlecase
16
15
  # raise(
@@ -54,3 +53,25 @@ module Osso
54
53
  end
55
54
  end
56
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
+ #
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # -*- SkipSchemaAnnotations
4
+
3
5
  require 'sinatra/activerecord'
4
6
 
5
7
  module Osso
@@ -9,11 +9,11 @@ module Osso
9
9
  has_many :identity_providers
10
10
  has_many :redirect_uris
11
11
 
12
- before_validation :setup, on: :create
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 default_redirect_uri
16
+ def primary_redirect_uri
17
17
  redirect_uris.find(&:primary)
18
18
  end
19
19
 
@@ -21,12 +21,26 @@ module Osso
21
21
  redirect_uris.map(&:uri)
22
22
  end
23
23
 
24
- private
25
-
26
- def setup
24
+ def generate_secrets
27
25
  self.identifier = SecureRandom.hex(16)
28
- self.secret = SecureRandom.hex(64)
26
+ self.secret = SecureRandom.hex(32)
29
27
  end
30
28
  end
31
29
  end
32
30
  end
31
+
32
+ # == Schema Information
33
+ #
34
+ # Table name: oauth_clients
35
+ #
36
+ # id :uuid not null, primary key
37
+ # name :string not null
38
+ # secret :string not null
39
+ # identifier :string not null
40
+ # created_at :datetime not null
41
+ # updated_at :datetime not null
42
+ #
43
+ # Indexes
44
+ #
45
+ # index_oauth_clients_on_identifier (identifier) UNIQUE
46
+ #
@@ -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
+ #
@@ -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
+ #
@@ -36,6 +36,12 @@ module Osso
36
36
 
37
37
  erb :admin
38
38
  end
39
+
40
+ get '/config/:id' do
41
+ admin_protected!
42
+
43
+ erb :admin
44
+ end
39
45
  end
40
46
  end
41
47
  end
@@ -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)
@@ -40,7 +40,7 @@ module Osso
40
40
  post '/saml/:id/callback' do
41
41
  provider = Models::IdentityProvider.find(params[:id])
42
42
  oauth_client = provider.oauth_client
43
- redirect_uri = env['redirect_uri'] || oauth_client.default_redirect_uri.uri
43
+ redirect_uri = env['redirect_uri'] || oauth_client.primary_redirect_uri.uri
44
44
 
45
45
  attributes = env['omniauth.auth']&.
46
46
  extra&.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Osso
4
- VERSION = '0.0.3.8'
4
+ VERSION = '0.0.3.13'
5
5
  end