osso 0.0.3.13 → 0.0.3.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.yml +8 -1
  3. data/.rubocop.yml +1 -0
  4. data/Gemfile.lock +2 -2
  5. data/bin/publish +18 -0
  6. data/lib/osso/graphql/mutation.rb +6 -2
  7. data/lib/osso/graphql/mutations/base_mutation.rb +18 -5
  8. data/lib/osso/graphql/mutations/configure_identity_provider.rb +8 -10
  9. data/lib/osso/graphql/mutations/create_enterprise_account.rb +2 -0
  10. data/lib/osso/graphql/mutations/create_identity_provider.rb +14 -5
  11. data/lib/osso/graphql/mutations/create_oauth_client.rb +1 -3
  12. data/lib/osso/graphql/mutations/delete_enterprise_account.rb +9 -11
  13. data/lib/osso/graphql/mutations/delete_oauth_client.rb +1 -3
  14. data/lib/osso/graphql/mutations/regenerate_oauth_credentials.rb +1 -3
  15. data/lib/osso/graphql/mutations/set_redirect_uris.rb +2 -4
  16. data/lib/osso/graphql/query.rb +7 -0
  17. data/lib/osso/graphql/resolvers.rb +1 -0
  18. data/lib/osso/graphql/resolvers/base_resolver.rb +21 -0
  19. data/lib/osso/graphql/resolvers/enterprise_account.rb +1 -11
  20. data/lib/osso/graphql/resolvers/enterprise_accounts.rb +2 -2
  21. data/lib/osso/graphql/resolvers/oauth_clients.rb +2 -2
  22. data/lib/osso/graphql/types.rb +1 -1
  23. data/lib/osso/graphql/types/admin_user.rb +22 -0
  24. data/lib/osso/graphql/types/base_object.rb +22 -0
  25. data/lib/osso/graphql/types/enterprise_account.rb +0 -5
  26. data/lib/osso/graphql/types/identity_provider.rb +0 -6
  27. data/lib/osso/graphql/types/oauth_client.rb +2 -4
  28. data/lib/osso/graphql/types/redirect_uri.rb +2 -4
  29. data/lib/osso/helpers/auth.rb +35 -15
  30. data/lib/osso/lib/route_map.rb +2 -2
  31. data/lib/osso/models/identity_provider.rb +6 -12
  32. data/lib/osso/models/oauth_client.rb +1 -0
  33. data/lib/osso/models/redirect_uri.rb +0 -11
  34. data/lib/osso/routes/admin.rb +2 -2
  35. data/lib/osso/routes/auth.rb +29 -12
  36. data/lib/osso/routes/oauth.rb +25 -18
  37. data/lib/osso/version.rb +1 -1
  38. data/spec/graphql/mutations/configure_identity_provider_spec.rb +17 -4
  39. data/spec/graphql/mutations/create_enterprise_account_spec.rb +13 -4
  40. data/spec/graphql/mutations/create_identity_provider_spec.rb +18 -6
  41. data/spec/graphql/mutations/create_oauth_client_spec.rb +10 -3
  42. data/spec/graphql/mutations/delete_enterprise_account_spec.rb +18 -4
  43. data/spec/graphql/mutations/delete_oauth_client_spec.rb +8 -4
  44. data/spec/graphql/query/enterprise_account_spec.rb +21 -6
  45. data/spec/graphql/query/enterprise_accounts_spec.rb +4 -2
  46. data/spec/graphql/query/identity_provider_spec.rb +16 -6
  47. data/spec/graphql/query/oauth_clients_spec.rb +10 -7
  48. data/spec/models/identity_provider_spec.rb +12 -0
  49. data/spec/routes/auth_spec.rb +18 -0
  50. data/spec/routes/oauth_spec.rb +5 -2
  51. data/spec/support/views/error.erb +0 -0
  52. metadata +10 -6
  53. data/lib/osso/graphql/types/user.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f73668d92fba6a919487f77d474b948af28e79b33d60a1c1e2cec8104b0dcff
4
- data.tar.gz: f736cdc806facf653635a037f8b9abb8202cda2e811b3b75a2dc52332b12ddab
3
+ metadata.gz: 6b1068b7192ca709b9ba61cccaae62a9d98b350c756f88890f48b7fe2f7e4780
4
+ data.tar.gz: c9b499428182dc6c920624fdbcd36c2e0d3b5a14e83259d95b506c3bbbf2efad
5
5
  SHA512:
6
- metadata.gz: 3ea4d47b42b9d2e0ac48833e37ed3375d41d60eefac31166ba81dd86ae3b38f059518beeae625324af095f9c4da4433c83aefd92cb7038cc5e924293e26956e4
7
- data.tar.gz: 36969b24b9047a0ab3920e206590697083a314618765dbe7352a5563b4bd93aaca7b50524f442eb994052db594393500a4a157a527d483049f49765367495b39
6
+ metadata.gz: 49a87999664fb1d809ced917bbd85c37e69c995c1e287683d0b84b3bbc97b9c24a19b31ffc0225a21c88fec9caa059b2b3bddd0d7b2e37480d7e2f92d0651cb9
7
+ data.tar.gz: 7a94be7b14bdb164d4f18fab52c9f7453f79e2547cfff606aa7ae854b281ac03017e176ea1b697130bc4a0a5191c31519f94aab974ebcd56a69ddc228e67eee9
@@ -5,4 +5,11 @@ steps:
5
5
  - bundle exec rake db:drop
6
6
  - bundle exec rake db:create
7
7
  - RACK_ENV=test bundle exec rake db:migrate
8
- - bundle exec rspec
8
+ - bundle exec rspec
9
+
10
+ - block: ":rubygems: Publish :red_button:"
11
+ branches: "main"
12
+
13
+ - name: "Push :rubygems:"
14
+ commands: "./bin/publish"
15
+ branches: "main"
@@ -1,4 +1,5 @@
1
1
  AllCops:
2
+ TargetRubyVersion: 2.6.0
2
3
  Exclude:
3
4
  - db/**/*
4
5
  - lib/osso/db/**/*
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- osso (0.0.3.13)
4
+ osso (0.0.3.18)
5
5
  activesupport (>= 6.0.3.2)
6
6
  graphql
7
7
  jwt
@@ -66,7 +66,7 @@ GEM
66
66
  method_source (1.0.0)
67
67
  mini_portile2 (2.4.0)
68
68
  minitest (5.14.1)
69
- multi_json (1.14.1)
69
+ multi_json (1.15.0)
70
70
  mustermann (1.1.1)
71
71
  ruby2_keywords (~> 0.0.1)
72
72
  nokogiri (1.10.9)
@@ -0,0 +1,18 @@
1
+ #!/bin/sh
2
+ # Scriptacular - gemify.sh
3
+ # Create a Ruby gem and push it to rubygems.org
4
+ # Copyright 2013 Christopher Simpkins
5
+ # MIT License
6
+
7
+ GEM_NAME="osso-rb"
8
+ GEMSPEC_SUFFIX=".gemspec"
9
+
10
+ # run the gem build and parse for the gem release filename
11
+ GEM_BUILD_NAME=$(gem build "$GEM_NAME$GEMSPEC_SUFFIX" | awk '/File/ {print $2}' -)
12
+
13
+ if [ -z "$GEM_BUILD_NAME" ]; then
14
+ echo "The gem build failed." >&2
15
+ exit 1
16
+ fi
17
+
18
+ gem push $GEM_BUILD_NAME
@@ -6,16 +6,20 @@ module Osso
6
6
  module GraphQL
7
7
  module Types
8
8
  class MutationType < BaseObject
9
- field :add_redirect_uris_to_oauth_client, mutation: Mutations::AddRedirectUrisToOauthClient, null: false
10
9
  field :configure_identity_provider, mutation: Mutations::ConfigureIdentityProvider, null: true
11
10
  field :create_identity_provider, mutation: Mutations::CreateIdentityProvider
12
11
  field :create_enterprise_account, mutation: Mutations::CreateEnterpriseAccount
13
12
  field :create_oauth_client, mutation: Mutations::CreateOauthClient
14
13
  field :delete_enterprise_account, mutation: Mutations::DeleteEnterpriseAccount
15
14
  field :delete_oauth_client, mutation: Mutations::DeleteOauthClient
16
- field :delete_redirect_uri, mutation: Mutations::DeleteRedirectUri
17
15
  field :set_redirect_uris, mutation: Mutations::SetRedirectUris
18
16
  field :regenerate_oauth_credentials, mutation: Mutations::RegenerateOauthCredentials
17
+
18
+ def self.authorized?(_object, _context)
19
+ # mutations are prevented from executing with ready? so
20
+ # its a bit odd that this hides it
21
+ true
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -15,13 +15,26 @@ module Osso
15
15
  error.merge(data: nil)
16
16
  end
17
17
 
18
- def ready?(enterprise_account_id: nil, domain: nil, identity_provider_id: nil, **args)
19
- return true if context[:scope] == :admin
18
+ def ready?(**args)
19
+ return true if internal_ready?
20
20
 
21
- domain ||= account_domain(enterprise_account_id) || provider_domain(identity_provider_id)
22
- return true if domain == context[:scope]
21
+ return true if domain_ready?(args[:domain] || domain(**args))
23
22
 
24
- raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{args[:domain]}"
23
+ raise ::GraphQL::ExecutionError, 'This user lacks the permission to make the requested changes'
24
+ end
25
+
26
+ def admin_ready?
27
+ context[:scope] == 'admin'
28
+ end
29
+
30
+ def internal_ready?
31
+ return true if admin_ready?
32
+
33
+ context[:scope] == 'internal'
34
+ end
35
+
36
+ def domain_ready?(domain)
37
+ context[:email].split('@')[1] == domain
25
38
  end
26
39
 
27
40
  def account_domain(id)
@@ -13,22 +13,20 @@ module Osso
13
13
  field :identity_provider, Types::IdentityProvider, null: false
14
14
  field :errors, [String], null: false
15
15
 
16
- def resolve(id:, **args)
17
- provider = Osso::Models::IdentityProvider.find(id)
16
+ def resolve(**args)
17
+ provider = identity_provider(**args)
18
18
 
19
19
  return response_data(identity_provider: provider) if provider.update(args)
20
20
 
21
- response_error(errors: provder.errors.messages)
21
+ response_error(errors: provider.errors.messages)
22
22
  end
23
23
 
24
- def ready?(id:, **_args)
25
- return true if context[:scope] == :admin
26
-
27
- domain = Osso::Models::IdentityProvider.find(id)&.domain
28
-
29
- return true if domain == context[:scope]
24
+ def domain(**args)
25
+ identity_provider(**args)&.domain
26
+ end
30
27
 
31
- raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{domain}"
28
+ def identity_provider(id:, **_args)
29
+ @identity_provider ||= Osso::Models::IdentityProvider.find(id)
32
30
  end
33
31
  end
34
32
  end
@@ -8,12 +8,14 @@ module Osso
8
8
 
9
9
  argument :domain, String, required: true
10
10
  argument :name, String, required: true
11
+ argument :oauth_client_id, ID, required: false
11
12
 
12
13
  field :enterprise_account, Types::EnterpriseAccount, null: false
13
14
  field :errors, [String], null: false
14
15
 
15
16
  def resolve(**args)
16
17
  enterprise_account = Osso::Models::EnterpriseAccount.new(args)
18
+ enterprise_account.oauth_client_id ||= context[:oauth_client_id]
17
19
 
18
20
  return response_data(enterprise_account: enterprise_account) if enterprise_account.save
19
21
 
@@ -12,18 +12,27 @@ module Osso
12
12
  field :identity_provider, Types::IdentityProvider, null: false
13
13
  field :errors, [String], null: false
14
14
 
15
- def resolve(enterprise_account_id:, service: nil)
16
- enterprise_account = Osso::Models::EnterpriseAccount.find(enterprise_account_id)
17
- identity_provider = enterprise_account.identity_providers.build(
18
- enterprise_account_id: enterprise_account_id,
15
+ def resolve(service: nil, **args)
16
+ customer = enterprise_account(**args)
17
+
18
+ identity_provider = customer.identity_providers.build(
19
19
  service: service,
20
- domain: enterprise_account.domain,
20
+ domain: customer.domain,
21
+ oauth_client_id: customer.oauth_client_id,
21
22
  )
22
23
 
23
24
  return response_data(identity_provider: identity_provider) if identity_provider.save
24
25
 
25
26
  response_error(errors: identity_provider.errors.full_messages)
26
27
  end
28
+
29
+ def domain(**args)
30
+ enterprise_account(**args)&.domain
31
+ end
32
+
33
+ def enterprise_account(enterprise_account_id:, **_args)
34
+ @enterprise_account ||= Osso::Models::EnterpriseAccount.find(enterprise_account_id)
35
+ end
27
36
  end
28
37
  end
29
38
  end
@@ -20,9 +20,7 @@ module Osso
20
20
  end
21
21
 
22
22
  def ready?(*)
23
- return true if context[:scope] == :admin
24
-
25
- raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
23
+ admin_ready?
26
24
  end
27
25
  end
28
26
  end
@@ -11,22 +11,20 @@ module Osso
11
11
  field :enterprise_account, Types::EnterpriseAccount, null: true
12
12
  field :errors, [String], null: false
13
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)
14
+ def enterprise_account(id:, **_args)
15
+ @enterprise_account ||= Osso::Models::EnterpriseAccount.find(id)
20
16
  end
21
17
 
22
- def ready?(id:)
23
- return true if context[:scope] == :admin
18
+ def resolve(**args)
19
+ customer = enterprise_account(**args)
24
20
 
25
- domain = account_domain(id)
21
+ return response_data(enterprise_account: nil) if customer.destroy
26
22
 
27
- return true if domain == context[:scope]
23
+ response_error(errors: customer.errors.full_messages)
24
+ end
28
25
 
29
- raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{domain}"
26
+ def domain(**args)
27
+ enterprise_account(**args).domain
30
28
  end
31
29
  end
32
30
  end
@@ -20,9 +20,7 @@ module Osso
20
20
  end
21
21
 
22
22
  def ready?(*)
23
- return true if context[:scope] == :admin
24
-
25
- raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
23
+ admin_ready?
26
24
  end
27
25
  end
28
26
  end
@@ -21,9 +21,7 @@ module Osso
21
21
  end
22
22
 
23
23
  def ready?(*)
24
- return true if context[:scope] == :admin
25
-
26
- raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
24
+ admin_ready?
27
25
  end
28
26
  end
29
27
  end
@@ -24,14 +24,12 @@ module Osso
24
24
  end
25
25
 
26
26
  def ready?(*)
27
- return true if context[:scope] == :admin
28
-
29
- raise ::GraphQL::ExecutionError, 'Only admin users may mutate OauthClients'
27
+ admin_ready?
30
28
  end
31
29
 
32
30
  def update_existing(oauth_client, redirect_uris)
33
31
  oauth_client.redirect_uris.each do |redirect|
34
- updating_index = redirect_uris.index{ |incoming| incoming[:id] == redirect.id }
32
+ updating_index = redirect_uris.index { |incoming| incoming[:id] == redirect.id }
35
33
 
36
34
  if updating_index
37
35
  updating = redirect_uris.delete_at(updating_index)
@@ -32,6 +32,13 @@ module Osso
32
32
  ) do
33
33
  argument :id, ID, required: true
34
34
  end
35
+
36
+ field(
37
+ :current_user,
38
+ Types::AdminUser,
39
+ null: false,
40
+ resolve: ->(_obj, _args, context) { context.to_h },
41
+ )
35
42
  end
36
43
  end
37
44
  end
@@ -7,6 +7,7 @@ module Osso
7
7
  end
8
8
  end
9
9
 
10
+ require_relative 'resolvers/base_resolver'
10
11
  require_relative 'resolvers/enterprise_account'
11
12
  require_relative 'resolvers/enterprise_accounts'
12
13
  require_relative 'resolvers/oauth_clients'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osso
4
+ module GraphQL
5
+ module Resolvers
6
+ class BaseResolver < ::GraphQL::Schema::Resolver
7
+ def admin_authorized?
8
+ context[:scope] == 'admin'
9
+ end
10
+
11
+ def internal_authorized?
12
+ %w[admin internal].include?(context[:scope])
13
+ end
14
+
15
+ def enterprise_authorized?(domain)
16
+ context[:scope] == domain
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -3,22 +3,12 @@
3
3
  module Osso
4
4
  module GraphQL
5
5
  module Resolvers
6
- class EnterpriseAccount < ::GraphQL::Schema::Resolver
6
+ class EnterpriseAccount < BaseResolver
7
7
  type Types::EnterpriseAccount, null: false
8
8
 
9
9
  def resolve(args)
10
- return unless admin? || enterprise_authorized?(args[:domain])
11
-
12
10
  Osso::Models::EnterpriseAccount.find_by(domain: args[:domain])
13
11
  end
14
-
15
- def admin?
16
- context[:scope] == :admin
17
- end
18
-
19
- def enterprise_authorized?(domain)
20
- context[:scope] == domain
21
- end
22
12
  end
23
13
  end
24
14
  end
@@ -3,11 +3,11 @@
3
3
  module Osso
4
4
  module GraphQL
5
5
  module Resolvers
6
- class EnterpriseAccounts < ::GraphQL::Schema::Resolver
6
+ class EnterpriseAccounts < BaseResolver
7
7
  type Types::EnterpriseAccount.connection_type, null: true
8
8
 
9
9
  def resolve(sort_column: nil, sort_order: nil)
10
- return Array(Osso::Models::EnterpriseAccount.find_by(domain: context[:scope])) if context[:scope] != :admin
10
+ return Array(Osso::Models::EnterpriseAccount.find_by(domain: context[:scope])) unless internal_authorized?
11
11
 
12
12
  accounts = Osso::Models::EnterpriseAccount
13
13
 
@@ -3,11 +3,11 @@
3
3
  module Osso
4
4
  module GraphQL
5
5
  module Resolvers
6
- class OAuthClients < ::GraphQL::Schema::Resolver
6
+ class OAuthClients < BaseResolver
7
7
  type [Types::OauthClient], null: true
8
8
 
9
9
  def resolve
10
- return Osso::Models::OauthClient.all if context[:scope] == :admin
10
+ Osso::Models::OauthClient.all
11
11
  end
12
12
  end
13
13
  end
@@ -9,6 +9,7 @@ require_relative 'types/base_connection'
9
9
  require_relative 'types/base_object'
10
10
  require_relative 'types/base_enum'
11
11
  require_relative 'types/base_input_object'
12
+ require_relative 'types/admin_user'
12
13
  require_relative 'types/identity_provider_service'
13
14
  require_relative 'types/identity_provider_status'
14
15
  require_relative 'types/identity_provider'
@@ -16,4 +17,3 @@ require_relative 'types/enterprise_account'
16
17
  require_relative 'types/redirect_uri'
17
18
  require_relative 'types/redirect_uri_input'
18
19
  require_relative 'types/oauth_client'
19
- require_relative 'types/user'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+
5
+ module Osso
6
+ module GraphQL
7
+ module Types
8
+ class AdminUser < Types::BaseObject
9
+ description 'An Admin User of Osso'
10
+
11
+ field :id, ID, null: false
12
+ field :email, String, null: false
13
+ field :scope, String, null: false
14
+ field :oauth_client_id, ID, null: true
15
+
16
+ def self.authorized?(_object, _context)
17
+ true
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -10,6 +10,28 @@ module Osso
10
10
 
11
11
  field :created_at, ::GraphQL::Types::ISO8601DateTime, null: false
12
12
  field :updated_at, ::GraphQL::Types::ISO8601DateTime, null: false
13
+
14
+ def self.admin_authorized?(context)
15
+ context[:scope] == 'admin'
16
+ end
17
+
18
+ def self.internal_authorized?(context)
19
+ %w[admin internal].include?(context[:scope])
20
+ end
21
+
22
+ def self.enterprise_authorized?(context, domain)
23
+ return false unless domain
24
+
25
+ context[:email].split('@')[1] == domain
26
+ end
27
+
28
+ def self.authorized?(object, context)
29
+ # we first receive the payload object as a hash, but can depend on the
30
+ # return type to hide the actual objects non-admins shouldn't see
31
+ return true if object.class == Hash
32
+
33
+ internal_authorized?(context) || enterprise_authorized?(context, object&.domain)
34
+ end
13
35
  end
14
36
  end
15
37
  end