osso 0.0.3.8 → 0.0.3.9
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.
- checksums.yaml +4 -4
- data/.buildkite/pipeline.yml +5 -3
- data/Gemfile.lock +5 -1
- data/bin/annotate +1 -0
- data/db/schema.rb +9 -43
- 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 +3 -1
- data/lib/osso/graphql/mutations.rb +3 -1
- 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/resolvers/oauth_clients.rb +1 -1
- data/lib/osso/graphql/types/base_object.rb +2 -0
- data/lib/osso/graphql/types/oauth_client.rb +13 -1
- data/lib/osso/helpers/auth.rb +11 -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 +22 -1
- data/lib/osso/models/models.rb +2 -0
- data/lib/osso/models/oauth_client.rb +17 -1
- data/lib/osso/models/redirect_uri.rb +17 -0
- data/lib/osso/models/user.rb +22 -0
- 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 +1 -1
- 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/identity_provider_spec.rb +1 -1
- data/spec/graphql/query/{oauth_clients_account_spec.rb → oauth_clients_spec.rb} +2 -0
- metadata +27 -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
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3f0c8535a6ba6dd39ada0f3ba0aa0617ff96bd880ef6985149c0ecbeca57bc1a
         | 
| 4 | 
            +
              data.tar.gz: da6bec63d5e071b1c0520e42cd67c3971851445bfad8ec597f1b9d1aef0759d8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3e3938abd7b541d6e272cb1b1420e9f4dc75738edd763cc1c35e82db4b315852c125f268ad8ed36528373252c23bdea79b7ac865711abb1c52159cae709c47c5
         | 
| 7 | 
            +
              data.tar.gz: fa63314128c1833ddd1136ea1cdacee8e8f4cbfb92a6eaffc0c8ae8dfc0ccb93b62effcac55e0cf916033a32cd1941e5ea915959f032ed6a983133711f4610e0
         | 
    
        data/.buildkite/pipeline.yml
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            steps:
         | 
| 2 2 | 
             
              - name: ":rspec:"
         | 
| 3 3 | 
             
                commands: 
         | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 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
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                osso (0.0.3. | 
| 4 | 
            +
                osso (0.0.3.9)
         | 
| 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
         | 
    
        data/bin/annotate
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            annotate --require osso.rb  --models --model-dir ./lib/osso/models/ --position bottom -k -i
         | 
    
        data/db/schema.rb
    CHANGED
    
    | @@ -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:  | 
| 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
         | 
| @@ -9,7 +9,9 @@ module Osso | |
| 9 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 : | 
| 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/ | 
| 12 | 
            +
            require_relative 'mutations/create_oauth_client'
         | 
| 13 | 
            +
            require_relative 'mutations/delete_enterprise_account'
         | 
| 14 | 
            +
            require_relative 'mutations/delete_oauth_client'
         | 
| @@ -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
         | 
| @@ -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,18 @@ 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 | 
            +
             | 
| 18 | 
            +
                    def client_id
         | 
| 19 | 
            +
                      object.identifier
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def client_secret
         | 
| 23 | 
            +
                      object.secret
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    def self.authorized?(object, context)
         | 
| 27 | 
            +
                      super && context[:scope] == :admin
         | 
| 28 | 
            +
                    end
         | 
| 17 29 | 
             
                  end
         | 
| 18 30 | 
             
                end
         | 
| 19 31 | 
             
              end
         | 
    
        data/lib/osso/helpers/auth.rb
    CHANGED
    
    | @@ -15,12 +15,7 @@ module Osso | |
| 15 15 | 
             
                  end
         | 
| 16 16 |  | 
| 17 17 | 
             
                  def enterprise_authorized?(_domain)
         | 
| 18 | 
            -
                    payload, _args =  | 
| 19 | 
            -
                      token,
         | 
| 20 | 
            -
                      ENV['JWT_HMAC_SECRET'],
         | 
| 21 | 
            -
                      true,
         | 
| 22 | 
            -
                      { algorithm: 'HS256' },
         | 
| 23 | 
            -
                    )
         | 
| 18 | 
            +
                    payload, _args = decode(token)
         | 
| 24 19 |  | 
| 25 20 | 
             
                    @current_scope = payload['scope']
         | 
| 26 21 |  | 
| @@ -36,12 +31,7 @@ module Osso | |
| 36 31 | 
             
                  end
         | 
| 37 32 |  | 
| 38 33 | 
             
                  def admin_authorized?
         | 
| 39 | 
            -
                    payload, _args =  | 
| 40 | 
            -
                      token,
         | 
| 41 | 
            -
                      ENV['JWT_HMAC_SECRET'],
         | 
| 42 | 
            -
                      true,
         | 
| 43 | 
            -
                      { algorithm: 'HS256' },
         | 
| 44 | 
            -
                    )
         | 
| 34 | 
            +
                    payload, _args = decode(token)
         | 
| 45 35 |  | 
| 46 36 | 
             
                    if payload['scope'] == 'admin'
         | 
| 47 37 | 
             
                      @current_scope = :admin
         | 
| @@ -66,6 +56,15 @@ module Osso | |
| 66 56 |  | 
| 67 57 | 
             
                    redirect request.path
         | 
| 68 58 | 
             
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def decode(token)
         | 
| 61 | 
            +
                    JWT.decode(
         | 
| 62 | 
            +
                      token,
         | 
| 63 | 
            +
                      ENV['JWT_HMAC_SECRET'],
         | 
| 64 | 
            +
                      true,
         | 
| 65 | 
            +
                      { algorithm: 'HS256' },
         | 
| 66 | 
            +
                    )
         | 
| 67 | 
            +
                  end
         | 
| 69 68 | 
             
                end
         | 
| 70 69 | 
             
              end
         | 
| 71 70 | 
             
            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 | 
            +
            #
         | 
    
        data/lib/osso/models/models.rb
    CHANGED
    
    
| @@ -25,8 +25,24 @@ module Osso | |
| 25 25 |  | 
| 26 26 | 
             
                  def setup
         | 
| 27 27 | 
             
                    self.identifier = SecureRandom.hex(16)
         | 
| 28 | 
            -
                    self.secret = SecureRandom.hex( | 
| 28 | 
            +
                    self.secret = SecureRandom.hex(32)
         | 
| 29 29 | 
             
                  end
         | 
| 30 30 | 
             
                end
         | 
| 31 31 | 
             
              end
         | 
| 32 32 | 
             
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            # == Schema Information
         | 
| 35 | 
            +
            #
         | 
| 36 | 
            +
            # Table name: oauth_clients
         | 
| 37 | 
            +
            #
         | 
| 38 | 
            +
            #  id         :uuid             not null, primary key
         | 
| 39 | 
            +
            #  name       :string           not null
         | 
| 40 | 
            +
            #  secret     :string           not null
         | 
| 41 | 
            +
            #  identifier :string           not null
         | 
| 42 | 
            +
            #  created_at :datetime         not null
         | 
| 43 | 
            +
            #  updated_at :datetime         not null
         | 
| 44 | 
            +
            #
         | 
| 45 | 
            +
            # Indexes
         | 
| 46 | 
            +
            #
         | 
| 47 | 
            +
            #  index_oauth_clients_on_identifier  (identifier) UNIQUE
         | 
| 48 | 
            +
            #
         | 
| @@ -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 | 
            +
            #
         | 
    
        data/lib/osso/models/user.rb
    CHANGED
    
    | @@ -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 | 
            +
            #
         | 
    
        data/lib/osso/version.rb
    CHANGED
    
    
    
        data/osso-rb.gemspec
    CHANGED
    
    | @@ -28,6 +28,7 @@ Gem::Specification.new do |spec| | |
| 28 28 | 
             
              spec.add_runtime_dependency 'sinatra-activerecord'
         | 
| 29 29 | 
             
              spec.add_runtime_dependency 'sinatra-contrib'
         | 
| 30 30 |  | 
| 31 | 
            +
              spec.add_development_dependency 'annotate', '~> 3.1'
         | 
| 31 32 | 
             
              spec.add_development_dependency 'bundler', '~> 2.1'
         | 
| 32 33 | 
             
              spec.add_development_dependency 'pry'
         | 
| 33 34 |  | 
| @@ -47,3 +47,25 @@ FactoryBot.define do | |
| 47 47 | 
             
                end
         | 
| 48 48 | 
             
              end
         | 
| 49 49 | 
             
            end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            # == Schema Information
         | 
| 52 | 
            +
            #
         | 
| 53 | 
            +
            # Table name: identity_providers
         | 
| 54 | 
            +
            #
         | 
| 55 | 
            +
            #  id                    :uuid             not null, primary key
         | 
| 56 | 
            +
            #  service               :string
         | 
| 57 | 
            +
            #  domain                :string           not null
         | 
| 58 | 
            +
            #  sso_url               :string
         | 
| 59 | 
            +
            #  sso_cert              :text
         | 
| 60 | 
            +
            #  enterprise_account_id :uuid
         | 
| 61 | 
            +
            #  oauth_client_id       :uuid
         | 
| 62 | 
            +
            #  status                :enum             default("PENDING")
         | 
| 63 | 
            +
            #  created_at            :datetime
         | 
| 64 | 
            +
            #  updated_at            :datetime
         | 
| 65 | 
            +
            #
         | 
| 66 | 
            +
            # Indexes
         | 
| 67 | 
            +
            #
         | 
| 68 | 
            +
            #  index_identity_providers_on_domain                 (domain)
         | 
| 69 | 
            +
            #  index_identity_providers_on_enterprise_account_id  (enterprise_account_id)
         | 
| 70 | 
            +
            #  index_identity_providers_on_oauth_client_id        (oauth_client_id)
         | 
| 71 | 
            +
            #
         | 
| @@ -47,7 +47,7 @@ describe Osso::GraphQL::Schema do | |
| 47 47 | 
             
                  let(:current_scope) { :admin }
         | 
| 48 48 | 
             
                  it 'configures an identity provider' do
         | 
| 49 49 | 
             
                    expect(subject.dig('data', 'configureIdentityProvider', 'identityProvider', 'status')).
         | 
| 50 | 
            -
                      to eq(' | 
| 50 | 
            +
                      to eq('Configured')
         | 
| 51 51 | 
             
                  end
         | 
| 52 52 | 
             
                end
         | 
| 53 53 |  | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'spec_helper'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Osso::GraphQL::Schema do
         | 
| 6 | 
            +
              describe 'CreateOauthClient' do
         | 
| 7 | 
            +
                let(:variables) do
         | 
| 8 | 
            +
                  {
         | 
| 9 | 
            +
                    input: {
         | 
| 10 | 
            +
                      name: Faker::Company.name,
         | 
| 11 | 
            +
                    },
         | 
| 12 | 
            +
                  }
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                let(:mutation) do
         | 
| 16 | 
            +
                  <<~GRAPHQL
         | 
| 17 | 
            +
                     mutation CreateOauthClient($input: CreateOauthClientInput!) {
         | 
| 18 | 
            +
                      createOauthClient(input: $input) {
         | 
| 19 | 
            +
                        oauthClient {
         | 
| 20 | 
            +
                          id
         | 
| 21 | 
            +
                          name
         | 
| 22 | 
            +
                          clientId
         | 
| 23 | 
            +
                          clientSecret
         | 
| 24 | 
            +
                        }
         | 
| 25 | 
            +
                      }
         | 
| 26 | 
            +
                    }
         | 
| 27 | 
            +
                  GRAPHQL
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                subject do
         | 
| 31 | 
            +
                  described_class.execute(
         | 
| 32 | 
            +
                    mutation,
         | 
| 33 | 
            +
                    variables: variables,
         | 
| 34 | 
            +
                    context: { scope: current_scope },
         | 
| 35 | 
            +
                  )
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                describe 'for an admin user' do
         | 
| 39 | 
            +
                  let(:current_scope) { :admin }
         | 
| 40 | 
            +
                  it 'creates an OauthClient' do
         | 
| 41 | 
            +
                    expect { subject }.to change { Osso::Models::OauthClient.count }.by(1)
         | 
| 42 | 
            +
                    expect(subject.dig('data', 'createOauthClient', 'oauthClient', 'clientId')).
         | 
| 43 | 
            +
                      to_not be_nil
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                describe 'for an email scoped user' do
         | 
| 48 | 
            +
                  let(:current_scope) { 'foo.com' }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  it 'does not create an OauthClient Account' do
         | 
| 51 | 
            +
                    expect { subject }.to_not(change { Osso::Models::OauthClient.count })
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'spec_helper'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Osso::GraphQL::Schema do
         | 
| 6 | 
            +
              describe 'DeleteEnterpriseAccount' do
         | 
| 7 | 
            +
                let(:domain) { Faker::Internet.domain_name }
         | 
| 8 | 
            +
                let!(:enterprise_account) { create(:enterprise_account, domain: domain) }
         | 
| 9 | 
            +
                let(:variables) do
         | 
| 10 | 
            +
                  {
         | 
| 11 | 
            +
                    input: {
         | 
| 12 | 
            +
                      id: enterprise_account.id,
         | 
| 13 | 
            +
                    },
         | 
| 14 | 
            +
                  }
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                let(:mutation) do
         | 
| 18 | 
            +
                  <<~GRAPHQL
         | 
| 19 | 
            +
                     mutation DeleteEnterpriseAccount($input: DeleteEnterpriseAccountInput!) {
         | 
| 20 | 
            +
                      deleteEnterpriseAccount(input: $input) {
         | 
| 21 | 
            +
                        enterpriseAccount {
         | 
| 22 | 
            +
                          id
         | 
| 23 | 
            +
                        }
         | 
| 24 | 
            +
                      }
         | 
| 25 | 
            +
                    }
         | 
| 26 | 
            +
                  GRAPHQL
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                subject do
         | 
| 30 | 
            +
                  described_class.execute(
         | 
| 31 | 
            +
                    mutation,
         | 
| 32 | 
            +
                    variables: variables,
         | 
| 33 | 
            +
                    context: { scope: current_scope },
         | 
| 34 | 
            +
                  )
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                describe 'for an admin user' do
         | 
| 38 | 
            +
                  let(:current_scope) { :admin }
         | 
| 39 | 
            +
                  it 'deletes an Enterprise Account' do
         | 
| 40 | 
            +
                    expect { subject }.to change { Osso::Models::EnterpriseAccount.count }.by(-1)
         | 
| 41 | 
            +
                    expect(subject.dig('data', 'createEnterpriseAccount', 'enterpriseAccount')).
         | 
| 42 | 
            +
                      to be_nil
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                describe 'for an email scoped user' do
         | 
| 47 | 
            +
                  let(:current_scope) { domain }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  it 'deletes the Enterprise Account' do
         | 
| 50 | 
            +
                    expect { subject }.to change { Osso::Models::EnterpriseAccount.count }.by(-1)
         | 
| 51 | 
            +
                    expect(subject.dig('data', 'createEnterpriseAccount', 'enterpriseAccount')).
         | 
| 52 | 
            +
                      to be_nil
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
                describe 'for the wrong email scoped user' do
         | 
| 56 | 
            +
                  let(:current_scope) { 'foo.com' }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  it 'does not delete the Enterprise Account' do
         | 
| 59 | 
            +
                    expect { subject }.to_not(change { Osso::Models::EnterpriseAccount.count })
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'spec_helper'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Osso::GraphQL::Schema do
         | 
| 6 | 
            +
              describe 'DeleteOauthClient' do
         | 
| 7 | 
            +
                let!(:oauth_client) { create(:oauth_client) }
         | 
| 8 | 
            +
                let(:variables) do
         | 
| 9 | 
            +
                  {
         | 
| 10 | 
            +
                    input: {
         | 
| 11 | 
            +
                      id: oauth_client.id,
         | 
| 12 | 
            +
                    },
         | 
| 13 | 
            +
                  }
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                let(:mutation) do
         | 
| 17 | 
            +
                  <<~GRAPHQL
         | 
| 18 | 
            +
                     mutation DeleteOauthClient($input: DeleteOauthClientInput!) {
         | 
| 19 | 
            +
                      deleteOauthClient(input: $input) {
         | 
| 20 | 
            +
                        oauthClient {
         | 
| 21 | 
            +
                          id
         | 
| 22 | 
            +
                        }
         | 
| 23 | 
            +
                      }
         | 
| 24 | 
            +
                    }
         | 
| 25 | 
            +
                  GRAPHQL
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                subject do
         | 
| 29 | 
            +
                  described_class.execute(
         | 
| 30 | 
            +
                    mutation,
         | 
| 31 | 
            +
                    variables: variables,
         | 
| 32 | 
            +
                    context: { scope: current_scope },
         | 
| 33 | 
            +
                  )
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                describe 'for an admin user' do
         | 
| 37 | 
            +
                  let(:current_scope) { :admin }
         | 
| 38 | 
            +
                  it 'deletes the OauthClient' do
         | 
| 39 | 
            +
                    expect { subject }.to change { Osso::Models::OauthClient.count }.by(-1)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                describe 'for an email scoped user' do
         | 
| 44 | 
            +
                  let(:current_scope) { 'foo.com' }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  it 'does not create an OauthClient Account' do
         | 
| 47 | 
            +
                    expect { subject }.to_not(change { Osso::Models::OauthClient.count })
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -55,7 +55,7 @@ describe Osso::GraphQL::Schema do | |
| 55 55 |  | 
| 56 56 | 
             
                describe 'for the wrong email scoped user' do
         | 
| 57 57 | 
             
                  let(:current_scope) { 'bar.com' }
         | 
| 58 | 
            -
             | 
| 58 | 
            +
             | 
| 59 59 | 
             
                  it 'returns Enterprise Account for domain' do
         | 
| 60 60 | 
             
                    expect(subject['errors']).to_not be_empty
         | 
| 61 61 | 
             
                    expect(subject.dig('data', 'enterpriseAccount')).to be_nil
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: osso
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0.3. | 
| 4 | 
            +
              version: 0.0.3.9
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sam Bauch
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020-07- | 
| 11 | 
            +
            date: 2020-07-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -178,6 +178,20 @@ dependencies: | |
| 178 178 | 
             
                - - ">="
         | 
| 179 179 | 
             
                  - !ruby/object:Gem::Version
         | 
| 180 180 | 
             
                    version: '0'
         | 
| 181 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 182 | 
            +
              name: annotate
         | 
| 183 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 184 | 
            +
                requirements:
         | 
| 185 | 
            +
                - - "~>"
         | 
| 186 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 187 | 
            +
                    version: '3.1'
         | 
| 188 | 
            +
              type: :development
         | 
| 189 | 
            +
              prerelease: false
         | 
| 190 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 191 | 
            +
                requirements:
         | 
| 192 | 
            +
                - - "~>"
         | 
| 193 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 194 | 
            +
                    version: '3.1'
         | 
| 181 195 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 182 196 | 
             
              name: bundler
         | 
| 183 197 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -210,6 +224,7 @@ description: This gem includes the main functionality for Osso apps, | |
| 210 224 | 
             
            email:
         | 
| 211 225 | 
             
            - sbauch@gmail.com
         | 
| 212 226 | 
             
            executables:
         | 
| 227 | 
            +
            - annotate
         | 
| 213 228 | 
             
            - console
         | 
| 214 229 | 
             
            - setup
         | 
| 215 230 | 
             
            extensions: []
         | 
| @@ -229,6 +244,7 @@ files: | |
| 229 244 | 
             
            - LICENSE
         | 
| 230 245 | 
             
            - README.md
         | 
| 231 246 | 
             
            - Rakefile
         | 
| 247 | 
            +
            - bin/annotate
         | 
| 232 248 | 
             
            - bin/console
         | 
| 233 249 | 
             
            - bin/setup
         | 
| 234 250 | 
             
            - config/database.yml
         | 
| @@ -238,7 +254,6 @@ files: | |
| 238 254 | 
             
            - lib/osso/Rakefile
         | 
| 239 255 | 
             
            - lib/osso/db/migrate/20190909230109_enable_uuid.rb
         | 
| 240 256 | 
             
            - lib/osso/db/migrate/20200328135750_create_users.rb
         | 
| 241 | 
            -
            - lib/osso/db/migrate/20200328143303_create_oauth_tables.rb
         | 
| 242 257 | 
             
            - lib/osso/db/migrate/20200328143305_create_identity_providers.rb
         | 
| 243 258 | 
             
            - lib/osso/db/migrate/20200411184535_add_provider_id_to_users.rb
         | 
| 244 259 | 
             
            - lib/osso/db/migrate/20200411192645_create_enterprise_accounts.rb
         | 
| @@ -251,6 +266,8 @@ files: | |
| 251 266 | 
             
            - lib/osso/db/migrate/20200715154211_rename_idp_fields_on_identity_provider_to_sso.rb
         | 
| 252 267 | 
             
            - lib/osso/db/migrate/20200715205801_add_name_to_enterprise_account.rb
         | 
| 253 268 | 
             
            - lib/osso/db/migrate/20200722230116_add_identity_provider_status_enum_and_use_on_identity_providers.rb
         | 
| 269 | 
            +
            - lib/osso/db/migrate/20200723153750_add_missing_timestamps.rb
         | 
| 270 | 
            +
            - lib/osso/db/migrate/20200723162228_drop_unneeded_tables.rb
         | 
| 254 271 | 
             
            - lib/osso/graphql/.DS_Store
         | 
| 255 272 | 
             
            - lib/osso/graphql/mutation.rb
         | 
| 256 273 | 
             
            - lib/osso/graphql/mutations.rb
         | 
| @@ -258,7 +275,9 @@ files: | |
| 258 275 | 
             
            - lib/osso/graphql/mutations/configure_identity_provider.rb
         | 
| 259 276 | 
             
            - lib/osso/graphql/mutations/create_enterprise_account.rb
         | 
| 260 277 | 
             
            - lib/osso/graphql/mutations/create_identity_provider.rb
         | 
| 261 | 
            -
            - lib/osso/graphql/mutations/ | 
| 278 | 
            +
            - lib/osso/graphql/mutations/create_oauth_client.rb
         | 
| 279 | 
            +
            - lib/osso/graphql/mutations/delete_enterprise_account.rb
         | 
| 280 | 
            +
            - lib/osso/graphql/mutations/delete_oauth_client.rb
         | 
| 262 281 | 
             
            - lib/osso/graphql/query.rb
         | 
| 263 282 | 
             
            - lib/osso/graphql/resolvers.rb
         | 
| 264 283 | 
             
            - lib/osso/graphql/resolvers/enterprise_account.rb
         | 
| @@ -287,9 +306,6 @@ files: | |
| 287 306 | 
             
            - lib/osso/models/models.rb
         | 
| 288 307 | 
             
            - lib/osso/models/oauth_client.rb
         | 
| 289 308 | 
             
            - lib/osso/models/redirect_uri.rb
         | 
| 290 | 
            -
            - lib/osso/models/saml_provider.rb
         | 
| 291 | 
            -
            - lib/osso/models/saml_providers/azure_saml_provider.rb
         | 
| 292 | 
            -
            - lib/osso/models/saml_providers/okta_saml_provider.rb
         | 
| 293 309 | 
             
            - lib/osso/models/user.rb
         | 
| 294 310 | 
             
            - lib/osso/rake.rb
         | 
| 295 311 | 
             
            - lib/osso/routes/admin.rb
         | 
| @@ -310,10 +326,13 @@ files: | |
| 310 326 | 
             
            - spec/graphql/mutations/configure_identity_provider_spec.rb
         | 
| 311 327 | 
             
            - spec/graphql/mutations/create_enterprise_account_spec.rb
         | 
| 312 328 | 
             
            - spec/graphql/mutations/create_identity_provider_spec.rb
         | 
| 329 | 
            +
            - spec/graphql/mutations/create_oauth_client_spec.rb
         | 
| 330 | 
            +
            - spec/graphql/mutations/delete_enterprise_account_spec.rb
         | 
| 331 | 
            +
            - spec/graphql/mutations/delete_oauth_client_spec.rb
         | 
| 313 332 | 
             
            - spec/graphql/query/enterprise_account_spec.rb
         | 
| 314 333 | 
             
            - spec/graphql/query/enterprise_accounts_spec.rb
         | 
| 315 334 | 
             
            - spec/graphql/query/identity_provider_spec.rb
         | 
| 316 | 
            -
            - spec/graphql/query/ | 
| 335 | 
            +
            - spec/graphql/query/oauth_clients_spec.rb
         | 
| 317 336 | 
             
            - spec/models/azure_saml_provider_spec.rb
         | 
| 318 337 | 
             
            - spec/models/identity_provider_spec.rb
         | 
| 319 338 | 
             
            - spec/models/okta_saml_provider_spec.rb
         | 
| @@ -1,57 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            class CreateOauthTables < ActiveRecord::Migration[6.0]
         | 
| 4 | 
            -
              def change
         | 
| 5 | 
            -
                create_table :oauth_applications, id: :uuid do |t|
         | 
| 6 | 
            -
                  t.string  :name,    null: false
         | 
| 7 | 
            -
                  t.string  :secret,  null: false
         | 
| 8 | 
            -
                  t.text    :redirect_uri, null: false
         | 
| 9 | 
            -
                  t.string  :scopes,       null: false, default: ''
         | 
| 10 | 
            -
                  t.boolean :confidential, null: false, default: true
         | 
| 11 | 
            -
                  t.timestamps             null: false
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                create_table :oauth_access_grants, id: :uuid do |t|
         | 
| 15 | 
            -
                  t.uuid :resource_owner_id, null: false
         | 
| 16 | 
            -
                  t.references :application, type: :uuid, null: false
         | 
| 17 | 
            -
                  t.string   :token,             null: false
         | 
| 18 | 
            -
                  t.integer  :expires_in,        null: false
         | 
| 19 | 
            -
                  t.text     :redirect_uri,      null: false
         | 
| 20 | 
            -
                  t.datetime :created_at,        null: false
         | 
| 21 | 
            -
                  t.datetime :revoked_at
         | 
| 22 | 
            -
                  t.string   :scopes, null: false, default: ''
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                add_index :oauth_access_grants, :token, unique: true
         | 
| 26 | 
            -
                add_foreign_key(
         | 
| 27 | 
            -
                  :oauth_access_grants,
         | 
| 28 | 
            -
                  :oauth_applications,
         | 
| 29 | 
            -
                  column: :application_id
         | 
| 30 | 
            -
                )
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                create_table :oauth_access_tokens, id: :uuid do |t|
         | 
| 33 | 
            -
                  t.uuid :resource_owner_id
         | 
| 34 | 
            -
                  t.references :application, type: :uuid
         | 
| 35 | 
            -
                  t.string :token, null: false
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  t.string   :refresh_token
         | 
| 38 | 
            -
                  t.integer  :expires_in
         | 
| 39 | 
            -
                  t.datetime :revoked_at
         | 
| 40 | 
            -
                  t.datetime :created_at, null: false
         | 
| 41 | 
            -
                  t.string   :scopes
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  t.string   :previous_refresh_token, null: false, default: ''
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                add_index :oauth_access_tokens, :token, unique: true
         | 
| 47 | 
            -
                add_index :oauth_access_tokens, :refresh_token, unique: true
         | 
| 48 | 
            -
                add_foreign_key(
         | 
| 49 | 
            -
                  :oauth_access_tokens,
         | 
| 50 | 
            -
                  :oauth_applications,
         | 
| 51 | 
            -
                  column: :application_id
         | 
| 52 | 
            -
                )
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                add_foreign_key :oauth_access_grants, :users, column: :resource_owner_id
         | 
| 55 | 
            -
                add_foreign_key :oauth_access_tokens, :users, column: :resource_owner_id
         | 
| 56 | 
            -
              end
         | 
| 57 | 
            -
            end
         | 
| @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Osso
         | 
| 4 | 
            -
              module GraphQL
         | 
| 5 | 
            -
                module Mutations
         | 
| 6 | 
            -
                  class SetSamlProvider < BaseMutation
         | 
| 7 | 
            -
                    null false
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    argument :provider, Types::IdentityProviderService, required: true
         | 
| 10 | 
            -
                    argument :id, ID, required: true
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                    field :identity_provider, Types::IdentityProvider, null: false
         | 
| 13 | 
            -
                    field :errors, [String], null: false
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                    def resolve(provider:, id:)
         | 
| 16 | 
            -
                      identity_provider = Osso::Models::IdentityProvider.find(id)
         | 
| 17 | 
            -
                      identity_provider.service = provider
         | 
| 18 | 
            -
                      identity_provider.save!
         | 
| 19 | 
            -
                      {
         | 
| 20 | 
            -
                        identity_provider: identity_provider,
         | 
| 21 | 
            -
                        errors: [],
         | 
| 22 | 
            -
                      }
         | 
| 23 | 
            -
                    end
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
              end
         | 
| 27 | 
            -
            end
         | 
| @@ -1,49 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Osso
         | 
| 4 | 
            -
              module Models
         | 
| 5 | 
            -
                # Base class for SAML Providers
         | 
| 6 | 
            -
                class IdentityProvider < ActiveRecord::Base
         | 
| 7 | 
            -
                  NAME_FORMAT = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
         | 
| 8 | 
            -
                  belongs_to :enterprise_account
         | 
| 9 | 
            -
                  belongs_to :oauth_client
         | 
| 10 | 
            -
                  has_many :users
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  before_create :create_enterprise_account
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  # def name
         | 
| 15 | 
            -
                  #   raise(
         | 
| 16 | 
            -
                  #     NoMethodError,
         | 
| 17 | 
            -
                  #     '#name must be defined on each provider specific subclass',
         | 
| 18 | 
            -
                  #   )
         | 
| 19 | 
            -
                  # end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  # def saml_options
         | 
| 22 | 
            -
                  #   raise(
         | 
| 23 | 
            -
                  #     NoMethodError,
         | 
| 24 | 
            -
                  #     '#saml_options must be defined on each provider specific subclass',
         | 
| 25 | 
            -
                  #   )
         | 
| 26 | 
            -
                  # end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  def assertion_consumer_service_url
         | 
| 29 | 
            -
                    [
         | 
| 30 | 
            -
                      ENV.fetch('BASE_URL'),
         | 
| 31 | 
            -
                      'auth',
         | 
| 32 | 
            -
                      'saml',
         | 
| 33 | 
            -
                      id,
         | 
| 34 | 
            -
                      'callback',
         | 
| 35 | 
            -
                    ].join('/')
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                  alias acs_url assertion_consumer_service_url
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                  def create_enterprise_account
         | 
| 41 | 
            -
                    return if enterprise_account_id
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                    self.enterprise_account = Models::EnterpriseAccount.create(
         | 
| 44 | 
            -
                      domain: domain,
         | 
| 45 | 
            -
                    )
         | 
| 46 | 
            -
                  end
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
              end
         | 
| 49 | 
            -
            end
         | 
| @@ -1,22 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Osso
         | 
| 4 | 
            -
              module Models
         | 
| 5 | 
            -
                # Subclass for Azure / ADFS IDP instances
         | 
| 6 | 
            -
                class AzureSamlProvider < Models::IdentityProvider
         | 
| 7 | 
            -
                  def name
         | 
| 8 | 
            -
                    'Azure'
         | 
| 9 | 
            -
                  end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  def saml_options
         | 
| 12 | 
            -
                    attributes.slice(
         | 
| 13 | 
            -
                      'domain',
         | 
| 14 | 
            -
                      'idp_cert',
         | 
| 15 | 
            -
                      'idp_sso_target_url',
         | 
| 16 | 
            -
                    ).merge(
         | 
| 17 | 
            -
                      issuer: "id:#{id}",
         | 
| 18 | 
            -
                    ).symbolize_keys
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
              end
         | 
| 22 | 
            -
            end
         | 
| @@ -1,23 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Osso
         | 
| 4 | 
            -
              module Models
         | 
| 5 | 
            -
                # Subclass for Okta IDP instances
         | 
| 6 | 
            -
                class OktaSamlProvider < Models::IdentityProvider
         | 
| 7 | 
            -
                  def name
         | 
| 8 | 
            -
                    'Okta'
         | 
| 9 | 
            -
                  end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  def saml_options
         | 
| 12 | 
            -
                    attributes.slice(
         | 
| 13 | 
            -
                      'domain',
         | 
| 14 | 
            -
                      'idp_cert',
         | 
| 15 | 
            -
                      'idp_sso_target_url',
         | 
| 16 | 
            -
                    ).merge(
         | 
| 17 | 
            -
                      issuer: id,
         | 
| 18 | 
            -
                      name_identifier_format: NAME_FORMAT,
         | 
| 19 | 
            -
                    ).symbolize_keys
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         |