osso 0.0.3.6 → 0.0.3.11

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 (53) 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 +11 -54
  6. data/lib/osso/db/migrate/20200714223226_add_identity_provider_service_enum.rb +1 -1
  7. data/lib/osso/db/migrate/20200722230116_add_identity_provider_status_enum_and_use_on_identity_providers.rb +15 -0
  8. data/lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb +35 -0
  9. data/lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb +9 -0
  10. data/lib/osso/graphql/mutation.rb +4 -2
  11. data/lib/osso/graphql/mutations.rb +3 -1
  12. data/lib/osso/graphql/mutations/base_mutation.rb +8 -2
  13. data/lib/osso/graphql/mutations/configure_identity_provider.rb +10 -1
  14. data/lib/osso/graphql/mutations/create_oauth_client.rb +30 -0
  15. data/lib/osso/graphql/mutations/delete_enterprise_account.rb +34 -0
  16. data/lib/osso/graphql/mutations/delete_oauth_client.rb +30 -0
  17. data/lib/osso/graphql/query.rb +4 -1
  18. data/lib/osso/graphql/resolvers/enterprise_accounts.rb +12 -4
  19. data/lib/osso/graphql/resolvers/oauth_clients.rb +1 -1
  20. data/lib/osso/graphql/schema.rb +4 -0
  21. data/lib/osso/graphql/types.rb +2 -0
  22. data/lib/osso/graphql/types/base_connection.rb +15 -0
  23. data/lib/osso/graphql/types/base_object.rb +4 -0
  24. data/lib/osso/graphql/types/enterprise_account.rb +4 -0
  25. data/lib/osso/graphql/types/identity_provider.rb +8 -3
  26. data/lib/osso/graphql/types/identity_provider_status.rb +14 -0
  27. data/lib/osso/graphql/types/oauth_client.rb +13 -1
  28. data/lib/osso/helpers/auth.rb +11 -12
  29. data/lib/osso/models/access_token.rb +18 -0
  30. data/lib/osso/models/authorization_code.rb +20 -0
  31. data/lib/osso/models/enterprise_account.rb +20 -0
  32. data/lib/osso/models/identity_provider.rb +29 -0
  33. data/lib/osso/models/models.rb +2 -0
  34. data/lib/osso/models/oauth_client.rb +17 -1
  35. data/lib/osso/models/redirect_uri.rb +17 -0
  36. data/lib/osso/models/user.rb +22 -0
  37. data/lib/osso/version.rb +1 -1
  38. data/osso-rb.gemspec +1 -0
  39. data/spec/factories/identity_providers.rb +22 -0
  40. data/spec/graphql/mutations/configure_identity_provider_spec.rb +14 -4
  41. data/spec/graphql/mutations/create_oauth_client_spec.rb +55 -0
  42. data/spec/graphql/mutations/delete_enterprise_account_spec.rb +63 -0
  43. data/spec/graphql/mutations/delete_oauth_client_spec.rb +51 -0
  44. data/spec/graphql/query/enterprise_account_spec.rb +1 -1
  45. data/spec/graphql/query/enterprise_accounts_spec.rb +32 -18
  46. data/spec/graphql/query/identity_provider_spec.rb +9 -6
  47. data/spec/graphql/query/{oauth_clients_account_spec.rb → oauth_clients_spec.rb} +2 -0
  48. metadata +30 -8
  49. data/lib/osso/db/migrate/20200328143303_create_oauth_tables.rb +0 -57
  50. data/lib/osso/graphql/mutations/set_identity_provider.rb +0 -27
  51. data/lib/osso/models/saml_provider.rb +0 -49
  52. data/lib/osso/models/saml_providers/azure_saml_provider.rb +0 -22
  53. data/lib/osso/models/saml_providers/okta_saml_provider.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2d208f60074e354a988dd4f6d1e07409a8c5b9809371f2ab86e952c1cf52cb2
4
- data.tar.gz: a113355db7bb066f7f87fea0bf8313bc7f60d628380abb8f334fc5de8e7e2d29
3
+ metadata.gz: ffe9bf4e6f4de963af60c998d318a471e1ff3e33ef5a6c544c8923de762020bc
4
+ data.tar.gz: a994f84634c584268e517688ec62b61315da4fa1ab2ea05787305b34deb964f5
5
5
  SHA512:
6
- metadata.gz: fec8ba8811aa056a367f975f206309cf74148a2bb551f8b37073a5c084a8fdeb86433dcd55862e24fe1199ba0b9ac8f3d166fce74ab7ea61ac5faa0690426baf
7
- data.tar.gz: 20f63616bfc1619d503357be6cbabc114bd9a9402fdd7cdf3e0caa5415fb19dd4cf22a56dcdc6aa83c0b323cd77f4da529659e1455e3c277f4d4180d97e290d5
6
+ metadata.gz: 6c4e301385bb83a8ca5f7d66e4a3b3383c7ea3f58f395dc83e1cbadadb2a6896e1852ed787ae9a33a37a2871c3d5c28e5f33e072b7980ad904f958e95b4addb8
7
+ data.tar.gz: 8529f13cc30d05946b7fa798b117483dd20b9415d27b6caccecfff228a666b73bfd1f36ceb7e19d7977803159a56aff0eca9075cb380fe7fde3ce560a1847217
@@ -1,6 +1,8 @@
1
1
  steps:
2
2
  - name: ":rspec:"
3
3
  commands:
4
- - "bundle install"
5
- - "bundle exec rake db:test:prepare"
6
- - "bundle exec rspec"
4
+ - bundle install
5
+ - bundle exec rake db:drop
6
+ - bundle exec rake db:create
7
+ - RACK_ENV=test bundle exec rake db:migrate
8
+ - bundle exec rspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- osso (0.0.3.6)
4
+ osso (0.0.3.11)
5
5
  activesupport (>= 6.0.3.2)
6
6
  graphql
7
7
  jwt
@@ -32,6 +32,9 @@ GEM
32
32
  addressable (2.7.0)
33
33
  public_suffix (>= 2.0.2, < 5.0)
34
34
  aes_key_wrap (1.0.1)
35
+ annotate (3.1.1)
36
+ activerecord (>= 3.2, < 7.0)
37
+ rake (>= 10.4, < 14.0)
35
38
  ast (2.4.1)
36
39
  attr_required (1.0.1)
37
40
  backports (3.18.1)
@@ -160,6 +163,7 @@ PLATFORMS
160
163
  ruby
161
164
 
162
165
  DEPENDENCIES
166
+ annotate (~> 3.1)
163
167
  bundler (~> 2.1)
164
168
  database_cleaner-active_record
165
169
  factory_bot
@@ -0,0 +1 @@
1
+ annotate --require osso.rb --models --model-dir ./lib/osso/models/ --position bottom -k -i
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2020_07_15_205801) do
13
+ ActiveRecord::Schema.define(version: 2020_07_23_162228) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "pgcrypto"
@@ -47,64 +47,21 @@ ActiveRecord::Schema.define(version: 2020_07_15_205801) do
47
47
  t.string "external_id"
48
48
  t.uuid "oauth_client_id"
49
49
  t.string "name", null: false
50
+ t.datetime "created_at", null: false
51
+ t.datetime "updated_at", null: false
50
52
  t.index ["domain"], name: "index_enterprise_accounts_on_domain", unique: true
51
53
  t.index ["oauth_client_id"], name: "index_enterprise_accounts_on_oauth_client_id"
52
54
  end
53
55
 
54
- create_table "identity_providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
55
- t.string "service"
56
- t.string "domain", null: false
57
- t.string "sso_url"
58
- t.text "sso_cert"
59
- t.uuid "enterprise_account_id"
60
- t.uuid "oauth_client_id"
61
- t.index ["domain"], name: "index_identity_providers_on_domain"
62
- t.index ["enterprise_account_id"], name: "index_identity_providers_on_enterprise_account_id"
63
- t.index ["oauth_client_id"], name: "index_identity_providers_on_oauth_client_id"
64
- end
65
-
66
- create_table "oauth_access_grants", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
67
- t.uuid "resource_owner_id", null: false
68
- t.uuid "application_id", null: false
69
- t.string "token", null: false
70
- t.integer "expires_in", null: false
71
- t.text "redirect_uri", null: false
72
- t.datetime "created_at", null: false
73
- t.datetime "revoked_at"
74
- t.string "scopes", default: "", null: false
75
- t.index ["application_id"], name: "index_oauth_access_grants_on_application_id"
76
- t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
77
- end
78
-
79
- create_table "oauth_access_tokens", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
80
- t.uuid "resource_owner_id"
81
- t.uuid "application_id"
82
- t.string "token", null: false
83
- t.string "refresh_token"
84
- t.integer "expires_in"
85
- t.datetime "revoked_at"
86
- t.datetime "created_at", null: false
87
- t.string "scopes"
88
- t.string "previous_refresh_token", default: "", null: false
89
- t.index ["application_id"], name: "index_oauth_access_tokens_on_application_id"
90
- t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
91
- t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
92
- end
93
-
94
- create_table "oauth_applications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
95
- t.string "name", null: false
96
- t.string "secret", null: false
97
- t.text "redirect_uri", null: false
98
- t.string "scopes", default: "", null: false
99
- t.boolean "confidential", default: true, null: false
100
- t.datetime "created_at", precision: 6, null: false
101
- t.datetime "updated_at", precision: 6, null: false
102
- end
56
+ # Could not dump table "identity_providers" because of following StandardError
57
+ # Unknown type 'identity_provider_status' for column 'status'
103
58
 
104
59
  create_table "oauth_clients", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
105
60
  t.string "name", null: false
106
61
  t.string "secret", null: false
107
62
  t.string "identifier", null: false
63
+ t.datetime "created_at", null: false
64
+ t.datetime "updated_at", null: false
108
65
  t.index ["identifier"], name: "index_oauth_clients_on_identifier", unique: true
109
66
  end
110
67
 
@@ -112,6 +69,8 @@ ActiveRecord::Schema.define(version: 2020_07_15_205801) do
112
69
  t.string "uri", null: false
113
70
  t.boolean "primary", default: false, null: false
114
71
  t.uuid "oauth_client_id"
72
+ t.datetime "created_at", null: false
73
+ t.datetime "updated_at", null: false
115
74
  t.index ["oauth_client_id"], name: "index_redirect_uris_on_oauth_client_id"
116
75
  t.index ["uri", "primary"], name: "index_redirect_uris_on_uri_and_primary", unique: true
117
76
  end
@@ -121,13 +80,11 @@ ActiveRecord::Schema.define(version: 2020_07_15_205801) do
121
80
  t.string "idp_id", null: false
122
81
  t.uuid "identity_provider_id"
123
82
  t.uuid "enterprise_account_id"
83
+ t.datetime "created_at", null: false
84
+ t.datetime "updated_at", null: false
124
85
  t.index ["email", "idp_id"], name: "index_users_on_email_and_idp_id", unique: true
125
86
  t.index ["enterprise_account_id"], name: "index_users_on_enterprise_account_id"
126
87
  end
127
88
 
128
- add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
129
- add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id"
130
- add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
131
- add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id"
132
89
  add_foreign_key "users", "identity_providers"
133
90
  end
@@ -4,7 +4,7 @@ class AddIdentityProviderServiceEnum < ActiveRecord::Migration[6.0]
4
4
  execute <<-SQL
5
5
  CREATE TYPE identity_provider_service AS ENUM ('OKTA', 'AZURE');
6
6
  SQL
7
- chnage_column :identity_providers, :service, :identity_provider_service
7
+ change_column :identity_providers, :service, :identity_provider_service
8
8
  end
9
9
 
10
10
  def down
@@ -0,0 +1,15 @@
1
+ class AddIdentityProviderStatusEnumAndUseOnIdentityProviders < ActiveRecord::Migration[6.0]
2
+ def up
3
+ execute <<~SQL
4
+ CREATE TYPE identity_provider_status AS ENUM ('PENDING', 'CONFIGURED', 'ACTIVE', 'ERROR');
5
+ SQL
6
+ add_column :identity_providers, :status, :identity_provider_status, default: 'PENDING'
7
+ end
8
+
9
+ def down
10
+ remove_column :identity_providers, :status
11
+ execute <<~SQL
12
+ DROP TYPE identity_provider_status;
13
+ SQL
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ class AddMissingTimestamps < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :enterprise_accounts, :created_at, :timestamp
4
+ add_column :enterprise_accounts, :updated_at, :timestamp
5
+ update "UPDATE enterprise_accounts SET created_at = NOW(), updated_at = NOW()"
6
+ change_column_null :enterprise_accounts, :created_at, false
7
+ change_column_null :enterprise_accounts, :updated_at, false
8
+
9
+
10
+ add_column :identity_providers, :created_at, :timestamp
11
+ add_column :identity_providers, :updated_at, :timestamp
12
+ update "UPDATE enterprise_accounts SET created_at = NOW(), updated_at = NOW()"
13
+ change_column_null :enterprise_accounts, :created_at, false
14
+ change_column_null :enterprise_accounts, :updated_at, false
15
+
16
+ add_column :oauth_clients, :created_at, :timestamp
17
+ add_column :oauth_clients, :updated_at, :timestamp
18
+ update "UPDATE oauth_clients SET created_at = NOW(), updated_at = NOW()"
19
+ change_column_null :oauth_clients, :created_at, false
20
+ change_column_null :oauth_clients, :updated_at, false
21
+
22
+ add_column :redirect_uris, :created_at, :timestamp
23
+ add_column :redirect_uris, :updated_at, :timestamp
24
+ update "UPDATE redirect_uris SET created_at = NOW(), updated_at = NOW()"
25
+ change_column_null :redirect_uris, :created_at, false
26
+ change_column_null :redirect_uris, :updated_at, false
27
+
28
+ add_column :users, :created_at, :timestamp
29
+ add_column :users, :updated_at, :timestamp
30
+ update "UPDATE users SET created_at = NOW(), updated_at = NOW()"
31
+ change_column_null :users, :created_at, false
32
+ change_column_null :users, :updated_at, false
33
+
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ class DropUnneededTables < ActiveRecord::Migration[6.0]
2
+ def change
3
+ drop_table(:oauth_grants, if_exists: true)
4
+ drop_table(:oauth_access_tokens, if_exists: true)
5
+ drop_table(:oauth_applications, if_exists: true)
6
+
7
+
8
+ end
9
+ end
@@ -6,10 +6,12 @@ module Osso
6
6
  module GraphQL
7
7
  module Types
8
8
  class MutationType < BaseObject
9
- field :configure_identity_provider, mutation: Mutations::ConfigureIdentityProvider
9
+ field :configure_identity_provider, mutation: Mutations::ConfigureIdentityProvider, null: true
10
10
  field :create_identity_provider, mutation: Mutations::CreateIdentityProvider
11
11
  field :create_enterprise_account, mutation: Mutations::CreateEnterpriseAccount
12
- field :set_identity_provider, mutation: Mutations::SetSamlProvider
12
+ field :create_oauth_client, mutation: Mutations::CreateOauthClient
13
+ field :delete_enterprise_account, mutation: Mutations::DeleteEnterpriseAccount
14
+ field :delete_oauth_client, mutation: Mutations::DeleteOauthClient
13
15
  end
14
16
  end
15
17
  end
@@ -9,4 +9,6 @@ require_relative 'mutations/base_mutation'
9
9
  require_relative 'mutations/configure_identity_provider'
10
10
  require_relative 'mutations/create_identity_provider'
11
11
  require_relative 'mutations/create_enterprise_account'
12
- require_relative 'mutations/set_identity_provider'
12
+ require_relative 'mutations/create_oauth_client'
13
+ require_relative 'mutations/delete_enterprise_account'
14
+ require_relative 'mutations/delete_oauth_client'
@@ -15,10 +15,10 @@ module Osso
15
15
  error.merge(data: nil)
16
16
  end
17
17
 
18
- def ready?(enterprise_account_id: nil, domain: nil, **args)
18
+ def ready?(enterprise_account_id: nil, domain: nil, identity_provider_id: nil, **args)
19
19
  return true if context[:scope] == :admin
20
20
 
21
- domain ||= account_domain(enterprise_account_id)
21
+ domain ||= account_domain(enterprise_account_id) || provider_domain(identity_provider_id)
22
22
  return true if domain == context[:scope]
23
23
 
24
24
  raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{args[:domain]}"
@@ -29,6 +29,12 @@ module Osso
29
29
 
30
30
  Osso::Models::EnterpriseAccount.find(id)&.domain
31
31
  end
32
+
33
+ def provider_domain(id)
34
+ return false unless id
35
+
36
+ Osso::Models::IdentityProvider.find(id)&.domain
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -16,11 +16,20 @@ module Osso
16
16
  def resolve(id:, **args)
17
17
  provider = Osso::Models::IdentityProvider.find(id)
18
18
 
19
- return unauthorized unless authorized?
20
19
  return response_data(identity_provider: provider) if provider.update(args)
21
20
 
22
21
  response_error(errors: provder.errors.messages)
23
22
  end
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]
30
+
31
+ raise ::GraphQL::ExecutionError, "This user lacks the scope to mutate records belonging to #{domain}"
32
+ end
24
33
  end
25
34
  end
26
35
  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
@@ -4,7 +4,10 @@ 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
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
8
11
  field :oauth_clients, null: true, resolver: Resolvers::OAuthClients
9
12
 
10
13
  field :enterprise_account, null: true, resolver: Resolvers::EnterpriseAccount do
@@ -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