osso 0.0.3.8 → 0.0.3.13

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73de8a2c5af9b7d62c94a5ed34c094455dc9b49b7345eb252308f7048e1164c0
4
- data.tar.gz: c37913b5f3a857245d588ad03155ece0c5aca99c22c4c56069f50d442cb74db5
3
+ metadata.gz: 4f73668d92fba6a919487f77d474b948af28e79b33d60a1c1e2cec8104b0dcff
4
+ data.tar.gz: f736cdc806facf653635a037f8b9abb8202cda2e811b3b75a2dc52332b12ddab
5
5
  SHA512:
6
- metadata.gz: 3047a07787aa764d105e77580846d60a943d4bd859baed5c861aebd8face6fb461342f3cccc01cc58e33d66310ba0d852185605fea09eb54d21c126aa149230c
7
- data.tar.gz: f61b3e5aa31946a69512762601d08ecc021be26a56df0b182fc826d53e7be0836ea019c90ad09fc6b927dc3b37ee8efbc01e6145c0c4af4ff97198b9cd89828c
6
+ metadata.gz: 3ea4d47b42b9d2e0ac48833e37ed3375d41d60eefac31166ba81dd86ae3b38f059518beeae625324af095f9c4da4433c83aefd92cb7038cc5e924293e26956e4
7
+ data.tar.gz: 36969b24b9047a0ab3920e206590697083a314618765dbe7352a5563b4bd93aaca7b50524f442eb994052db594393500a4a157a527d483049f49765367495b39
@@ -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.8)
4
+ osso (0.0.3.13)
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_22_230116) 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,6 +47,8 @@ ActiveRecord::Schema.define(version: 2020_07_22_230116) 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
@@ -54,48 +56,12 @@ ActiveRecord::Schema.define(version: 2020_07_22_230116) do
54
56
  # Could not dump table "identity_providers" because of following StandardError
55
57
  # Unknown type 'identity_provider_status' for column 'status'
56
58
 
57
- create_table "oauth_access_grants", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
58
- t.uuid "resource_owner_id", null: false
59
- t.uuid "application_id", null: false
60
- t.string "token", null: false
61
- t.integer "expires_in", null: false
62
- t.text "redirect_uri", null: false
63
- t.datetime "created_at", null: false
64
- t.datetime "revoked_at"
65
- t.string "scopes", default: "", null: false
66
- t.index ["application_id"], name: "index_oauth_access_grants_on_application_id"
67
- t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
68
- end
69
-
70
- create_table "oauth_access_tokens", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
71
- t.uuid "resource_owner_id"
72
- t.uuid "application_id"
73
- t.string "token", null: false
74
- t.string "refresh_token"
75
- t.integer "expires_in"
76
- t.datetime "revoked_at"
77
- t.datetime "created_at", null: false
78
- t.string "scopes"
79
- t.string "previous_refresh_token", default: "", null: false
80
- t.index ["application_id"], name: "index_oauth_access_tokens_on_application_id"
81
- t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
82
- t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
83
- end
84
-
85
- create_table "oauth_applications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
86
- t.string "name", null: false
87
- t.string "secret", null: false
88
- t.text "redirect_uri", null: false
89
- t.string "scopes", default: "", null: false
90
- t.boolean "confidential", default: true, null: false
91
- t.datetime "created_at", precision: 6, null: false
92
- t.datetime "updated_at", precision: 6, null: false
93
- end
94
-
95
59
  create_table "oauth_clients", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
96
60
  t.string "name", null: false
97
61
  t.string "secret", null: false
98
62
  t.string "identifier", null: false
63
+ t.datetime "created_at", null: false
64
+ t.datetime "updated_at", null: false
99
65
  t.index ["identifier"], name: "index_oauth_clients_on_identifier", unique: true
100
66
  end
101
67
 
@@ -103,6 +69,8 @@ ActiveRecord::Schema.define(version: 2020_07_22_230116) do
103
69
  t.string "uri", null: false
104
70
  t.boolean "primary", default: false, null: false
105
71
  t.uuid "oauth_client_id"
72
+ t.datetime "created_at", null: false
73
+ t.datetime "updated_at", null: false
106
74
  t.index ["oauth_client_id"], name: "index_redirect_uris_on_oauth_client_id"
107
75
  t.index ["uri", "primary"], name: "index_redirect_uris_on_uri_and_primary", unique: true
108
76
  end
@@ -112,13 +80,11 @@ ActiveRecord::Schema.define(version: 2020_07_22_230116) do
112
80
  t.string "idp_id", null: false
113
81
  t.uuid "identity_provider_id"
114
82
  t.uuid "enterprise_account_id"
83
+ t.datetime "created_at", null: false
84
+ t.datetime "updated_at", null: false
115
85
  t.index ["email", "idp_id"], name: "index_users_on_email_and_idp_id", unique: true
116
86
  t.index ["enterprise_account_id"], name: "index_users_on_enterprise_account_id"
117
87
  end
118
88
 
119
- add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
120
- add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id"
121
- add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
122
- add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id"
123
89
  add_foreign_key "users", "identity_providers"
124
90
  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,16 @@ 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
9
10
  field :configure_identity_provider, mutation: Mutations::ConfigureIdentityProvider, null: true
10
11
  field :create_identity_provider, mutation: Mutations::CreateIdentityProvider
11
12
  field :create_enterprise_account, mutation: Mutations::CreateEnterpriseAccount
12
- field :set_identity_provider, mutation: Mutations::SetSamlProvider
13
+ field :create_oauth_client, mutation: Mutations::CreateOauthClient
14
+ field :delete_enterprise_account, mutation: Mutations::DeleteEnterpriseAccount
15
+ field :delete_oauth_client, mutation: Mutations::DeleteOauthClient
16
+ field :delete_redirect_uri, mutation: Mutations::DeleteRedirectUri
17
+ field :set_redirect_uris, mutation: Mutations::SetRedirectUris
18
+ field :regenerate_oauth_credentials, mutation: Mutations::RegenerateOauthCredentials
13
19
  end
14
20
  end
15
21
  end
@@ -9,4 +9,8 @@ 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
+ require_relative 'mutations/regenerate_oauth_credentials'
16
+ require_relative 'mutations/set_redirect_uris'
@@ -21,7 +21,7 @@ module Osso
21
21
  response_error(errors: provder.errors.messages)
22
22
  end
23
23
 
24
- def ready?(id:, **args)
24
+ def ready?(id:, **_args)
25
25
  return true if context[:scope] == :admin
26
26
 
27
27
  domain = Osso::Models::IdentityProvider.find(id)&.domain
@@ -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
@@ -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
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osso
4
+ module GraphQL
5
+ module Mutations
6
+ class SetRedirectUris < BaseMutation
7
+ null false
8
+
9
+ argument :id, ID, required: true
10
+ argument :redirect_uris, [Types::RedirectUrisInput], required: true
11
+
12
+ field :oauth_client, Types::OauthClient, null: true
13
+ field :errors, [String], null: false
14
+
15
+ def resolve(id:, redirect_uris:)
16
+ oauth_client = Osso::Models::OauthClient.find(id)
17
+
18
+ update_existing(oauth_client, redirect_uris)
19
+ create_new(oauth_client, redirect_uris)
20
+
21
+ response_data(oauth_client: oauth_client.reload)
22
+ rescue StandardError => e
23
+ response_error(errors: e)
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
+
32
+ def update_existing(oauth_client, redirect_uris)
33
+ oauth_client.redirect_uris.each do |redirect|
34
+ updating_index = redirect_uris.index{ |incoming| incoming[:id] == redirect.id }
35
+
36
+ if updating_index
37
+ updating = redirect_uris.delete_at(updating_index)
38
+ redirect.update(updating.to_h)
39
+ next
40
+ end
41
+
42
+ redirect.destroy
43
+ end
44
+ end
45
+
46
+ def create_new(oauth_client, redirect_uris)
47
+ redirect_uris.map do |uri|
48
+ oauth_client.redirect_uris.create(uri.to_h.without(:id))
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -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
- field :oauth_clients, null: true, resolver: Resolvers::OAuthClients
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