├── .devcontainer ├── apt-install │ ├── devcontainer-feature.json │ └── install.sh └── devcontainer.json ├── .envrc ├── .github ├── FUNDING.yml ├── dependabot.yml ├── disabled │ └── truffle.yml └── workflows │ ├── ancient.yml │ ├── codeql-analysis.yml │ ├── coverage.yml │ ├── current.yml │ ├── dependency-review.yml │ ├── heads.yml │ ├── jruby.yml │ ├── legacy.yml │ ├── style.yml │ ├── supported.yml │ └── unsupported.yml ├── .gitignore ├── .idea ├── .gitignore ├── GitLink.xml ├── active-tab-highlighter.xml ├── dbnavigator.xml ├── developer-tools.xml ├── git_toolbox_blame.xml ├── git_toolbox_prj.xml ├── misc.xml ├── modules.xml ├── omniauth-identity.iml └── vcs.xml ├── .rspec ├── .rubocop.yml ├── .rubocop_gradual.lock ├── .simplecov ├── .tool-versions ├── .yard_gfm_support.rb ├── .yardopts ├── Appraisal.root.gemfile ├── Appraisals ├── CHANGELOG.md ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── Guardfile ├── LICENSE.txt ├── README.md ├── REEK ├── Rakefile ├── SECURITY.md ├── bin ├── _guard-core ├── appraisal ├── bundle ├── bundle-audit ├── bundler-audit ├── byebug ├── code_climate_reek ├── coderay ├── gem_checksums ├── github-markup ├── guard ├── htmldiff ├── httpclient ├── ldiff ├── listen ├── mongo_console ├── pry ├── racc ├── rackup ├── rake ├── rdoc ├── redcarpet ├── reek ├── ri ├── rspec ├── rubocop ├── rubocop-gradual ├── ruby-parse ├── ruby-rewrite ├── sequel ├── setup ├── standardrb ├── test-unit ├── thor ├── yard ├── yard-junk ├── yardoc └── yri ├── certs └── pboling.pem ├── checksums ├── omniauth-identity-3.1.0.gem.sha256 ├── omniauth-identity-3.1.0.gem.sha512 ├── omniauth-identity-3.1.1.gem.sha256 ├── omniauth-identity-3.1.1.gem.sha512 ├── omniauth-identity-3.1.2.gem.sha256 └── omniauth-identity-3.1.2.gem.sha512 ├── docs ├── OmniAuth.html ├── OmniAuth │ ├── Identity.html │ ├── Identity │ │ ├── Model.html │ │ ├── Model │ │ │ ├── ClassCreateApi.html │ │ │ ├── ClassMethods.html │ │ │ ├── InstancePersistedApi.html │ │ │ └── InstanceSaveApi.html │ │ ├── Models.html │ │ ├── Models │ │ │ ├── ActiveRecord.html │ │ │ ├── CouchPotatoModule.html │ │ │ ├── Mongoid.html │ │ │ ├── NoBrainer.html │ │ │ └── Sequel.html │ │ ├── SecurePassword.html │ │ ├── SecurePassword │ │ │ ├── ClassMethods.html │ │ │ └── InstanceMethodsOnActivation.html │ │ └── Version.html │ ├── Strategies.html │ └── Strategies │ │ └── Identity.html ├── _index.html ├── class_list.html ├── css │ ├── common.css │ ├── full_list.css │ └── style.css ├── file.CHANGELOG.html ├── file.CITATION.html ├── file.CODE_OF_CONDUCT.html ├── file.CONTRIBUTING.html ├── file.LICENSE.html ├── file.README.html ├── file.SECURITY.html ├── file_list.html ├── frames.html ├── index.html ├── js │ ├── app.js │ ├── full_list.js │ └── jquery.js ├── method_list.html └── top-level-namespace.html ├── gemfiles ├── ar_5_2.gemfile ├── ar_6_0.gemfile ├── ar_6_1.gemfile ├── ar_7_0.gemfile ├── ar_7_1.gemfile ├── ar_7_2.gemfile ├── ar_8_0.gemfile ├── audit.gemfile ├── couch_1.17.gemfile ├── couch_1.gemfile ├── coverage.gemfile ├── modular │ ├── audit.gemfile │ ├── coverage.gemfile │ ├── documentation.gemfile │ └── style.gemfile ├── mongoid_7.3.gemfile ├── mongoid_7.4.gemfile ├── mongoid_8.1.gemfile ├── mongoid_9.0.gemfile ├── sequel_5.86.gemfile └── style.gemfile ├── lib ├── omniauth-identity.rb └── omniauth │ ├── identity.rb │ ├── identity │ ├── model.rb │ ├── models │ │ ├── active_record.rb │ │ ├── couch_potato.rb │ │ ├── mongoid.rb │ │ ├── nobrainer.rb │ │ └── sequel.rb │ ├── secure_password.rb │ └── version.rb │ └── strategies │ └── identity.rb ├── omniauth-identity.gemspec ├── spec ├── config │ ├── byebug.rb │ └── rspec │ │ ├── rack_test.rb │ │ ├── rspec_block_is_expected.rb │ │ ├── rspec_core.rb │ │ └── version_gem.rb ├── omniauth │ ├── identity │ │ ├── model_spec.rb │ │ ├── secure_password_spec.rb │ │ └── version_spec.rb │ └── strategies │ │ └── identity_spec.rb ├── spec_helper.rb └── support │ └── shared_contexts │ ├── instance_with_instance_methods.rb │ ├── model_with_class_methods.rb │ └── persistable_model.rb ├── spec_ignored └── nobrainer_spec.rb └── spec_orms ├── active_record_spec.rb ├── couch_potato_spec.rb ├── mongoid_spec.rb ├── sequel_spec.rb └── support └── rspec_config ├── mongoid.rb └── mongoid.yml /.devcontainer/apt-install/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Apt Install Packages", 3 | "id": "apt-install", 4 | "version": "1.0.0", 5 | "description": "More packages are needed", 6 | "install": { 7 | "script": "install.sh" 8 | } 9 | } -------------------------------------------------------------------------------- /.devcontainer/apt-install/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | apt-get update -y 3 | apt-get install -y direnv default-jdk postgresql libpq-dev git zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev 4 | # Adds the direnv setup script to ~/.bashrc file (at the end) 5 | echo 'eval "$(direnv hook bash)"' >> ~/.bashrc -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ruby 3 | { 4 | "name": "Ruby", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/ruby:1-3-bookworm", 7 | 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | "features": { 10 | "./apt-install": {} 11 | }, 12 | 13 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 14 | // "forwardPorts": [], 15 | 16 | // Use 'postCreateCommand' to run commands after the container is created. 17 | "postCreateCommand": "bundle update --bundler", 18 | 19 | // Configure tool-specific properties. 20 | "customizations" : { 21 | "jetbrains" : { 22 | "backend" : "RubyMine" 23 | } 24 | }, 25 | 26 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 27 | // "remoteUser": "root" 28 | } 29 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | # Run any command in this library's bin/ without the bin/ prefix! 2 | PATH_add bin 3 | 4 | # Only add things to this file that should be shared with the team. 5 | 6 | # **dotenv** (See end of file for .env.local integration) 7 | # .env would override anything in this file, if enabled. 8 | # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments. 9 | # Override and customize anything below in your own .env.local 10 | # If you are using dotenv and not direnv, 11 | # copy the following `export` statements to your own .env file. 12 | 13 | ### General Ruby ### 14 | # Turn off Ruby Warnings about deprecated code 15 | # export RUBYOPT="-W0" 16 | 17 | ### External Testing Controls 18 | export K_SOUP_COV_DO=true # Means you want code coverage 19 | # Available formats are html, xml, rcov, lcov, json, tty 20 | export K_SOUP_COV_COMMAND_NAME="RSpec Coverage" 21 | export K_SOUP_COV_FORMATTERS="html,tty" 22 | export K_SOUP_COV_MIN_BRANCH=80 # Means you want to enforce X% branch coverage 23 | export K_SOUP_COV_MIN_LINE=91 # Means you want to enforce X% line coverage 24 | export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met 25 | export K_SOUP_COV_MULTI_FORMATTERS=true 26 | export MAX_ROWS=1 # Setting for simplecov-console gem for tty output, limits to the worst N rows of bad coverage 27 | 28 | # Internal Debugging Controls 29 | export DEBUG=false # do not allow byebug statements (override in .env.local) 30 | 31 | # .env would override anything in this file, if `dotenv` is uncommented below. 32 | # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments, 33 | # and that is why we generally want to leave it commented out. 34 | # dotenv 35 | 36 | # .env.local will override anything in this file. 37 | dotenv_if_exists .env.local 38 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | buy_me_a_coffee: pboling 4 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 5 | github: [pboling] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 6 | issuehunt: pboling # Replace with a single IssueHunt username 7 | ko_fi: pboling # Replace with a single Ko-fi username 8 | liberapay: pboling # Replace with a single Liberapay username 9 | open_collective: # Replace with a single Open Collective username 10 | patreon: galtzo # Replace with a single Patreon username 11 | polar: pboling 12 | thanks_dev: u/gh/pboling 13 | tidelift: rubygems/omniauth-identity # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: "rubocop-lts" 10 | - package-ecosystem: "github-actions" 11 | directory: "/" 12 | schedule: 13 | interval: "daily" 14 | -------------------------------------------------------------------------------- /.github/disabled/truffle.yml: -------------------------------------------------------------------------------- 1 | #name: Truffle 2 | # 3 | #env: 4 | # K_SOUP_COV_DO: false 5 | # 6 | #on: 7 | # push: 8 | # branches: 9 | # - 'main' 10 | # tags: 11 | # - '!*' # Do not execute on tags 12 | # pull_request: 13 | # branches: 14 | # - '*' 15 | # # Allow manually triggering the workflow. 16 | # workflow_dispatch: 17 | # 18 | #permissions: 19 | # contents: read 20 | # 21 | ## Cancels all previous workflow runs for the same branch that have not yet completed. 22 | #concurrency: 23 | # # The concurrency group contains the workflow name and the branch name. 24 | # group: "${{ github.workflow }}-${{ github.ref }}" 25 | # cancel-in-progress: true 26 | # 27 | #jobs: 28 | # test: 29 | # name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | # if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | # runs-on: ubuntu-22.04 32 | # continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | # env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | # BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | # strategy: 36 | # matrix: 37 | # include: 38 | # # NOTE: truffleruby does not support upgrading rubygems. 39 | # # truffleruby-22.3 (targets Ruby 3.0 compatibility) 40 | # - ruby: "truffleruby-22.3" 41 | # appraisal: "couch-1.17" 42 | # exec_cmd: "rake spec:orm:couch_potato" 43 | # gemfile: "Appraisal.root" 44 | # rubygems: default 45 | # bundler: default 46 | # 47 | # # truffleruby-23.0 (targets Ruby 3.1 compatibility) 48 | # - ruby: "truffleruby-23.0" 49 | # appraisal: "couch-1.17" 50 | # exec_cmd: "rake spec:orm:couch_potato" 51 | # gemfile: "Appraisal.root" 52 | # rubygems: default 53 | # bundler: default 54 | # 55 | # # truffleruby-23.1 (targets Ruby 3.2 compatibility) 56 | # - ruby: "truffleruby-23.1" 57 | # appraisal: "couch-1.17" 58 | # exec_cmd: "rake spec:orm:couch_potato" 59 | # gemfile: "Appraisal.root" 60 | # rubygems: default 61 | # bundler: default 62 | # 63 | # steps: 64 | # ### COUCHDB 65 | # - name: Start CouchDB 66 | # uses: iamssen/couchdb-github-action@master 67 | # if: "endsWith(matrix.exec_cmd, 'couch_potato')" 68 | # with: 69 | # couchdb-version: "3.4.1" 70 | # 71 | # ### SMOKE-TEST 72 | # - name: Smoke CouchDB 73 | # if: "endsWith(matrix.exec_cmd, 'couch_potato')" 74 | # run: | 75 | # curl -f http://127.0.0.1:5984/ 76 | # curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 77 | # 78 | # - name: Checkout 79 | # uses: actions/checkout@v4 80 | # 81 | # - name: Setup Ruby & RubyGems 82 | # uses: ruby/setup-ruby@v1 83 | # with: 84 | # ruby-version: ${{ matrix.ruby }} 85 | # rubygems: ${{ matrix.rubygems }} 86 | # bundler: ${{ matrix.bundler }} 87 | # bundler-cache: false 88 | # 89 | # # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 90 | # # We need to do this first to get appraisal installed. 91 | # # NOTE: This does not use the main Gemfile at all. 92 | # - name: Install Root Appraisal 93 | # run: bundle 94 | # - name: Appraisal for ${{ matrix.appraisal }} 95 | # run: bundle exec appraisal ${{ matrix.appraisal }} bundle 96 | # - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} 97 | # run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 98 | -------------------------------------------------------------------------------- /.github/workflows/ancient.yml: -------------------------------------------------------------------------------- 1 | name: MRI 2.4, 2.5 (EOL) 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | tags: 8 | - '!*' # Do not execute on tags 9 | pull_request: 10 | branches: 11 | - '*' 12 | # Allow manually triggering the workflow. 13 | workflow_dispatch: 14 | 15 | # Cancels all previous workflow runs for the same branch that have not yet completed. 16 | concurrency: 17 | # The concurrency group contains the workflow name and the branch name. 18 | group: "${{ github.workflow }}-${{ github.ref }}" 19 | cancel-in-progress: true 20 | 21 | jobs: 22 | test: 23 | name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 24 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 25 | runs-on: ubuntu-22.04 26 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 27 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 28 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 29 | strategy: 30 | fail-fast: false 31 | matrix: 32 | include: 33 | # # Ruby 2.4 34 | # - ruby: "2.4" 35 | # appraisal: "ar-5-2" 36 | # exec_cmd: "rake spec:orm:active_record" 37 | # gemfile: "Appraisal.root" 38 | # rubygems: "3.3.27" 39 | # bundler: "2.3.27" 40 | # - ruby: "2.4" 41 | # appraisal: "couch-1.17" 42 | # exec_cmd: "rake spec:orm:couch_potato" 43 | # gemfile: "Appraisal.root" 44 | # rubygems: "3.3.27" 45 | # bundler: "2.3.27" 46 | # - ruby: "2.4" 47 | # appraisal: "mongoid-7.3" 48 | # exec_cmd: "rake spec:orm:mongoid" 49 | # gemfile: "Appraisal.root" 50 | # rubygems: "3.3.27" 51 | # bundler: "2.3.27" 52 | # - ruby: "2.4" 53 | # appraisal: "sequel-5.86" 54 | # exec_cmd: "rake spec:orm:sequel" 55 | # gemfile: "Appraisal.root" 56 | # rubygems: "3.3.27" 57 | # bundler: "2.3.27" 58 | 59 | # Ruby 2.5 60 | - ruby: "2.5" 61 | appraisal: "ar-5-2" 62 | exec_cmd: "rake spec:orm:active_record" 63 | gemfile: "Appraisal.root" 64 | rubygems: "3.3.27" 65 | bundler: "2.3.27" 66 | - ruby: "2.5" 67 | appraisal: "ar-6-0" 68 | exec_cmd: "rake spec:orm:active_record" 69 | gemfile: "Appraisal.root" 70 | rubygems: "3.3.27" 71 | bundler: "2.3.27" 72 | - ruby: "2.5" 73 | appraisal: "ar-6-1" 74 | exec_cmd: "rake spec:orm:active_record" 75 | gemfile: "Appraisal.root" 76 | rubygems: "3.3.27" 77 | bundler: "2.3.27" 78 | - ruby: "2.5" 79 | appraisal: "couch-1.17" 80 | exec_cmd: "rake spec:orm:couch_potato" 81 | gemfile: "Appraisal.root" 82 | rubygems: "3.3.27" 83 | bundler: "2.3.27" 84 | - ruby: "2.5" 85 | appraisal: "mongoid-7.4" 86 | exec_cmd: "rake spec:orm:mongoid" 87 | gemfile: "Appraisal.root" 88 | rubygems: "3.3.27" 89 | bundler: "2.3.27" 90 | - ruby: "2.5" 91 | appraisal: "sequel-5.86" 92 | exec_cmd: "rake spec:orm:sequel" 93 | gemfile: "Appraisal.root" 94 | rubygems: "3.3.27" 95 | bundler: "2.3.27" 96 | 97 | steps: 98 | ### COUCHDB 99 | - name: Start CouchDB 100 | uses: iamssen/couchdb-github-action@master 101 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 102 | with: 103 | couchdb-version: "3.4.1" 104 | 105 | ### MONGODB 106 | - name: Start MongoDB 107 | uses: supercharge/mongodb-github-action@1.12.0 108 | if: "endsWith(matrix.exec_cmd, 'mongoid')" 109 | with: 110 | mongodb-version: "8.0" 111 | 112 | ### SMOKE-TEST 113 | - name: Smoke CouchDB 114 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 115 | run: | 116 | curl -f http://127.0.0.1:5984/ 117 | curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 118 | 119 | - name: Checkout 120 | uses: actions/checkout@v4 121 | 122 | - name: Setup Ruby & RubyGems 123 | uses: ruby/setup-ruby@v1 124 | with: 125 | ruby-version: ${{ matrix.ruby }} 126 | rubygems: ${{ matrix.rubygems }} 127 | bundler: ${{ matrix.bundler }} 128 | bundler-cache: false 129 | 130 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 131 | # We need to do this first to get appraisal installed. 132 | # NOTE: This does not use the main Gemfile at all. 133 | - name: Install Root Appraisal 134 | run: bundle 135 | - name: Appraisal for ${{ matrix.appraisal }} 136 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 137 | - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} 138 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 139 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main, "*-stable" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main, "*-stable" ] 20 | schedule: 21 | - cron: '35 1 * * 5' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'ruby' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v3 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v3 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v3 71 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Test Coverage 2 | 3 | env: 4 | K_SOUP_COV_MIN_BRANCH: 79 5 | K_SOUP_COV_MIN_LINE: 92 6 | K_SOUP_COV_MIN_HARD: true 7 | K_SOUP_COV_FORMATTERS: "html,rcov,lcov,json,tty" 8 | K_SOUP_COV_DO: true 9 | K_SOUP_COV_MULTI_FORMATTERS: true 10 | K_SOUP_COV_COMMAND_NAME: "RSpec Coverage" 11 | 12 | on: 13 | push: 14 | branches: 15 | - 'main' 16 | tags: 17 | - '!*' # Do not execute on tags 18 | pull_request: 19 | branches: 20 | - '*' 21 | # Allow manually triggering the workflow. 22 | workflow_dispatch: 23 | 24 | permissions: 25 | contents: read 26 | 27 | # Cancels all previous workflow runs for the same branch that have not yet completed. 28 | concurrency: 29 | # The concurrency group contains the workflow name and the branch name. 30 | group: "${{ github.workflow }}-${{ github.ref }}" 31 | cancel-in-progress: true 32 | 33 | jobs: 34 | coverage: 35 | name: Code Coverage on ${{ matrix.ruby }}@current 36 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 37 | runs-on: ubuntu-latest 38 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 39 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 40 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | include: 45 | # Coverage 46 | - ruby: "ruby" 47 | appraisal: "coverage" 48 | exec_cmd: "rake spec:orm:all" 49 | gemfile: "Appraisal.root" 50 | rubygems: latest 51 | bundler: latest 52 | 53 | steps: 54 | ### COUCHDB 55 | - name: Start CouchDB 56 | uses: iamssen/couchdb-github-action@master 57 | with: 58 | couchdb-version: "3.4.1" 59 | 60 | ### MONGODB 61 | - name: Start MongoDB 62 | uses: supercharge/mongodb-github-action@1.12.0 63 | with: 64 | mongodb-version: "8.0" 65 | 66 | ### SMOKE-TEST 67 | - name: Smoke CouchDB 68 | run: | 69 | curl -f http://127.0.0.1:5984/ 70 | curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 71 | 72 | - name: Checkout 73 | uses: actions/checkout@v4 74 | 75 | - name: Setup Ruby & RubyGems 76 | uses: ruby/setup-ruby@v1 77 | with: 78 | ruby-version: "${{ matrix.ruby }}" 79 | rubygems: "${{ matrix.rubygems }}" 80 | bundler: "${{ matrix.bundler }}" 81 | bundler-cache: false 82 | 83 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 84 | # We need to do this first to get appraisal installed. 85 | # NOTE: This does not use the main Gemfile at all. 86 | - name: Install Root Appraisal 87 | run: bundle 88 | - name: Appraisal for ${{ matrix.appraisal }} 89 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 90 | - name: Tests for ${{ matrix.ruby }}@current via ${{ matrix.exec_cmd }} 91 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 92 | 93 | - name: Code Coverage Summary Report 94 | uses: irongut/CodeCoverageSummary@v1.3.0 95 | if: ${{ github.event_name == 'pull_request' }} 96 | with: 97 | filename: ./coverage/coverage.xml 98 | badge: true 99 | fail_below_min: true 100 | format: markdown 101 | hide_branch_rate: false 102 | hide_complexity: true 103 | indicators: true 104 | output: both 105 | thresholds: '100 100' 106 | continue-on-error: ${{ matrix.experimental != 'false' }} 107 | 108 | - name: Add Coverage PR Comment 109 | uses: marocchino/sticky-pull-request-comment@v2 110 | if: ${{ github.event_name == 'pull_request' }} 111 | with: 112 | recreate: true 113 | path: code-coverage-results.md 114 | continue-on-error: ${{ matrix.experimental != 'false' }} 115 | 116 | - name: Upload coverage to Coveralls 117 | uses: coverallsapp/github-action@master 118 | with: 119 | github-token: ${{ secrets.GITHUB_TOKEN }} 120 | continue-on-error: ${{ matrix.experimental != 'false' }} 121 | 122 | - name: Upload coverage to CodeCov 123 | uses: codecov/codecov-action@v5 124 | with: 125 | fail_ci_if_error: true # optional (default = false) 126 | token: ${{ secrets.CODECOV_TOKEN }} 127 | verbose: true # optional (default = false) 128 | -------------------------------------------------------------------------------- /.github/workflows/current.yml: -------------------------------------------------------------------------------- 1 | # Targets the evergreen latest release of ruby, truffleruby, and jruby 2 | name: Current 3 | 4 | env: 5 | K_SOUP_COV_DO: false 6 | 7 | on: 8 | push: 9 | branches: 10 | - 'main' 11 | tags: 12 | - '!*' # Do not execute on tags 13 | pull_request: 14 | branches: 15 | - '*' 16 | # Allow manually triggering the workflow. 17 | workflow_dispatch: 18 | 19 | permissions: 20 | contents: read 21 | 22 | # Cancels all previous workflow runs for the same branch that have not yet completed. 23 | concurrency: 24 | # The concurrency group contains the workflow name and the branch name. 25 | group: "${{ github.workflow }}-${{ github.ref }}" 26 | cancel-in-progress: true 27 | 28 | jobs: 29 | test: 30 | name: Specs ${{ matrix.ruby }}@${{ matrix.appraisal }} 31 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 32 | runs-on: ubuntu-latest 33 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 34 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 35 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 36 | strategy: 37 | matrix: 38 | include: 39 | # Ruby 3.4 40 | - ruby: "3.4" 41 | appraisal: "ar-7-2" 42 | exec_cmd: "rake spec:orm:active_record" 43 | gemfile: "Appraisal.root" 44 | rubygems: latest 45 | bundler: latest 46 | - ruby: "3.4" 47 | appraisal: "ar-8-0" 48 | exec_cmd: "rake spec:orm:active_record" 49 | gemfile: "Appraisal.root" 50 | rubygems: latest 51 | bundler: latest 52 | - ruby: "3.4" 53 | appraisal: "couch-1.17" 54 | exec_cmd: "rake spec:orm:couch_potato" 55 | gemfile: "Appraisal.root" 56 | rubygems: latest 57 | bundler: latest 58 | - ruby: "3.4" 59 | appraisal: "mongoid-8.1" 60 | exec_cmd: "rake spec:orm:mongoid" 61 | gemfile: "Appraisal.root" 62 | rubygems: latest 63 | bundler: latest 64 | - ruby: "3.4" 65 | appraisal: "mongoid-9.0" 66 | exec_cmd: "rake spec:orm:mongoid" 67 | gemfile: "Appraisal.root" 68 | rubygems: latest 69 | bundler: latest 70 | - ruby: "3.4" 71 | appraisal: "sequel-5.86" 72 | exec_cmd: "rake spec:orm:sequel" 73 | gemfile: "Appraisal.root" 74 | rubygems: latest 75 | bundler: latest 76 | 77 | # # truffleruby-24.1 78 | # - ruby: "truffleruby" 79 | # appraisal: "ar-8-0" 80 | # exec_cmd: "rake spec:orm:active_record" 81 | # gemfile: "Appraisal.root" 82 | # rubygems: default 83 | # bundler: default 84 | 85 | # jruby-10.0 (targets Ruby 3.4 compatibility) 86 | - ruby: "jruby" 87 | appraisal: "ar-7-1" 88 | exec_cmd: "rake spec:orm:active_record" 89 | gemfile: "Appraisal.root" 90 | rubygems: default 91 | bundler: default 92 | 93 | steps: 94 | ### COUCHDB 95 | - name: Start CouchDB 96 | uses: iamssen/couchdb-github-action@master 97 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 98 | with: 99 | couchdb-version: "3.4.1" 100 | 101 | ### MONGODB 102 | - name: Start MongoDB 103 | uses: supercharge/mongodb-github-action@1.12.0 104 | if: "endsWith(matrix.exec_cmd, 'mongoid')" 105 | with: 106 | mongodb-version: "8.0" 107 | 108 | ### SMOKE-TEST 109 | - name: Smoke CouchDB 110 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 111 | run: | 112 | curl -f http://127.0.0.1:5984/ 113 | curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 114 | 115 | - name: Checkout 116 | uses: actions/checkout@v4 117 | 118 | - name: Setup Ruby & RubyGems 119 | uses: ruby/setup-ruby@v1 120 | with: 121 | ruby-version: ${{ matrix.ruby }} 122 | rubygems: ${{ matrix.rubygems }} 123 | bundler: ${{ matrix.bundler }} 124 | bundler-cache: false 125 | 126 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 127 | # We need to do this first to get appraisal installed. 128 | # NOTE: This does not use the main Gemfile at all. 129 | - name: Install Root Appraisal 130 | run: bundle 131 | - name: Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }} 132 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 133 | - name: Tests for ${{ matrix.ruby }}@${{ matrix.appraisal }} via ${{ matrix.exec_cmd }} 134 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 135 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 4 | # 5 | # Source repository: https://github.com/actions/dependency-review-action 6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 7 | name: 'Dependency Review' 8 | on: [pull_request] 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | dependency-review: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: 'Checkout Repository' 18 | uses: actions/checkout@v4 19 | - name: 'Dependency Review' 20 | uses: actions/dependency-review-action@v4 21 | -------------------------------------------------------------------------------- /.github/workflows/heads.yml: -------------------------------------------------------------------------------- 1 | name: Heads 2 | 3 | env: 4 | K_SOUP_COV_DO: false 5 | 6 | on: 7 | push: 8 | branches: 9 | - 'main' 10 | tags: 11 | - '!*' # Do not execute on tags 12 | pull_request: 13 | branches: 14 | - '*' 15 | # Allow manually triggering the workflow. 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | # Cancels all previous workflow runs for the same branch that have not yet completed. 22 | concurrency: 23 | # The concurrency group contains the workflow name and the branch name. 24 | group: "${{ github.workflow }}-${{ github.ref }}" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | test: 29 | name: Specs ${{ matrix.ruby }}@${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | runs-on: ubuntu-latest 32 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | strategy: 36 | fail-fast: true 37 | matrix: 38 | include: 39 | # NOTE: Heads use default rubygems / bundler; their defaults are custom, unreleased, and from the future! 40 | # ruby-head 41 | - ruby: "ruby-head" 42 | appraisal: "ar-8-0" 43 | exec_cmd: "rake spec:orm:active_record" 44 | gemfile: "Appraisal.root" 45 | rubygems: default 46 | bundler: default 47 | 48 | # # truffleruby-head 49 | # - ruby: "truffleruby-head" 50 | # appraisal: "couch-1.17" 51 | # exec_cmd: "rake spec:orm:couch_potato" 52 | # gemfile: "Appraisal.root" 53 | # rubygems: default 54 | # bundler: default 55 | 56 | # jruby-head 57 | - ruby: "jruby-head" 58 | appraisal: "ar-7-1" 59 | exec_cmd: "rake spec:orm:active_record" 60 | gemfile: "Appraisal.root" 61 | rubygems: default 62 | bundler: default 63 | 64 | steps: 65 | ### COUCHDB 66 | - name: Start CouchDB 67 | uses: iamssen/couchdb-github-action@master 68 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 69 | with: 70 | couchdb-version: "3.4.1" 71 | 72 | ### SMOKE-TEST 73 | - name: Smoke CouchDB 74 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 75 | run: | 76 | curl -f http://127.0.0.1:5984/ 77 | curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 78 | 79 | - name: Checkout 80 | uses: actions/checkout@v4 81 | 82 | - name: Setup Ruby & RubyGems 83 | uses: ruby/setup-ruby@v1 84 | with: 85 | ruby-version: ${{ matrix.ruby }} 86 | rubygems: ${{ matrix.rubygems }} 87 | bundler: ${{ matrix.bundler }} 88 | bundler-cache: false 89 | 90 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 91 | # We need to do this first to get appraisal installed. 92 | # NOTE: This does not use the main Gemfile at all. 93 | - name: Install Root Appraisal 94 | run: bundle 95 | - name: Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }} 96 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 97 | - name: Tests for ${{ matrix.ruby }}@${{ matrix.appraisal }} via ${{ matrix.exec_cmd }} 98 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 99 | -------------------------------------------------------------------------------- /.github/workflows/jruby.yml: -------------------------------------------------------------------------------- 1 | name: JRuby 2 | 3 | env: 4 | K_SOUP_COV_DO: false 5 | 6 | on: 7 | push: 8 | branches: 9 | - 'main' 10 | tags: 11 | - '!*' # Do not execute on tags 12 | pull_request: 13 | branches: 14 | - '*' 15 | # Allow manually triggering the workflow. 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | # Cancels all previous workflow runs for the same branch that have not yet completed. 22 | concurrency: 23 | # The concurrency group contains the workflow name and the branch name. 24 | group: "${{ github.workflow }}-${{ github.ref }}" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | test: 29 | name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | runs-on: ubuntu-22.04 32 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | strategy: 36 | matrix: 37 | include: 38 | # jruby-9.2 (targets Ruby 2.5 compatibility) 39 | - ruby: "jruby-9.2" 40 | appraisal: "ar-6-1" 41 | exec_cmd: "rake spec:orm:active_record" 42 | gemfile: "Appraisal.root" 43 | rubygems: default 44 | bundler: default 45 | 46 | # jruby-9.3 (targets Ruby 2.6 compatibility) 47 | - ruby: "jruby-9.3" 48 | appraisal: "ar-6-1" 49 | exec_cmd: "rake spec:orm:active_record" 50 | gemfile: "Appraisal.root" 51 | rubygems: default 52 | bundler: default 53 | 54 | # jruby-9.4 (targets Ruby 3.1 compatibility) 55 | - ruby: "jruby-9.4" 56 | appraisal: "ar-7-1" 57 | exec_cmd: "rake spec:orm:active_record" 58 | gemfile: "Appraisal.root" 59 | rubygems: default 60 | bundler: default 61 | 62 | steps: 63 | ### COUCHDB 64 | - name: Start CouchDB 65 | uses: iamssen/couchdb-github-action@master 66 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 67 | with: 68 | couchdb-version: "3.4.1" 69 | 70 | ### SMOKE-TEST 71 | - name: Smoke CouchDB 72 | if: "endsWith(matrix.exec_cmd, 'couch_potato')" 73 | run: | 74 | curl -f http://127.0.0.1:5984/ 75 | curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session 76 | 77 | - name: Checkout 78 | uses: actions/checkout@v4 79 | 80 | - name: Setup Ruby & RubyGems 81 | uses: ruby/setup-ruby@v1 82 | with: 83 | ruby-version: ${{ matrix.ruby }} 84 | rubygems: ${{ matrix.rubygems }} 85 | bundler: ${{ matrix.bundler }} 86 | bundler-cache: false 87 | 88 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 89 | # We need to do this first to get appraisal installed. 90 | # NOTE: This does not use the main Gemfile at all. 91 | - name: Install Root Appraisal 92 | run: bundle 93 | - name: Appraisal for ${{ matrix.appraisal }} 94 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 95 | - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} 96 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 97 | -------------------------------------------------------------------------------- /.github/workflows/legacy.yml: -------------------------------------------------------------------------------- 1 | name: MRI 3.0 (EOL) 2 | 3 | env: 4 | K_SOUP_COV_DO: false 5 | 6 | on: 7 | push: 8 | branches: 9 | - 'main' 10 | tags: 11 | - '!*' # Do not execute on tags 12 | pull_request: 13 | branches: 14 | - '*' 15 | # Allow manually triggering the workflow. 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | # Cancels all previous workflow runs for the same branch that have not yet completed. 22 | concurrency: 23 | # The concurrency group contains the workflow name and the branch name. 24 | group: "${{ github.workflow }}-${{ github.ref }}" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | test: 29 | name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | runs-on: ubuntu-22.04 32 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | strategy: 36 | fail-fast: false 37 | matrix: 38 | include: 39 | # Ruby 3.0 40 | - ruby: "ruby-3.0" 41 | appraisal: "ar-7-1" 42 | exec_cmd: "rake spec:orm:active_record" 43 | gemfile: "Appraisal.root" 44 | rubygems: '3.5.23' 45 | bundler: '2.5.23' 46 | 47 | steps: 48 | - name: Checkout 49 | uses: actions/checkout@v4 50 | 51 | - name: Setup Ruby & RubyGems 52 | uses: ruby/setup-ruby@v1 53 | with: 54 | ruby-version: ${{ matrix.ruby }} 55 | rubygems: ${{ matrix.rubygems }} 56 | bundler: ${{ matrix.bundler }} 57 | bundler-cache: false 58 | 59 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 60 | # We need to do this first to get appraisal installed. 61 | # NOTE: This does not use the main Gemfile at all. 62 | - name: Install Root Appraisal 63 | run: bundle 64 | - name: Appraisal for ${{ matrix.appraisal }} 65 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 66 | - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} 67 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 68 | -------------------------------------------------------------------------------- /.github/workflows/style.yml: -------------------------------------------------------------------------------- 1 | name: Style 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | tags: 8 | - '!*' # Do not execute on tags 9 | pull_request: 10 | branches: 11 | - '*' 12 | # Allow manually triggering the workflow. 13 | workflow_dispatch: 14 | 15 | permissions: 16 | contents: read 17 | 18 | # Cancels all previous workflow runs for the same branch that have not yet completed. 19 | concurrency: 20 | # The concurrency group contains the workflow name and the branch name. 21 | group: "${{ github.workflow }}-${{ github.ref }}" 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | rubocop: 26 | name: Style on ${{ matrix.ruby }}@current 27 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 28 | runs-on: ubuntu-latest 29 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 30 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 31 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | include: 36 | # Style 37 | - ruby: "ruby" 38 | appraisal: "style" 39 | exec_cmd: "rake rubocop_gradual:check" 40 | gemfile: "Appraisal.root" 41 | rubygems: latest 42 | bundler: latest 43 | 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v4 47 | 48 | - name: Setup Ruby & RubyGems 49 | uses: ruby/setup-ruby@v1 50 | with: 51 | ruby-version: ${{ matrix.ruby }} 52 | rubygems: ${{ matrix.rubygems }} 53 | bundler: ${{ matrix.bundler }} 54 | bundler-cache: false 55 | 56 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 57 | # We need to do this first to get appraisal installed. 58 | # NOTE: This does not use the main Gemfile at all. 59 | - name: Install Root Appraisal 60 | run: bundle 61 | - name: Appraisal for ${{ matrix.appraisal }} 62 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 63 | - name: Run ${{ matrix.appraisal }} checks via ${{ matrix.exec_cmd }} 64 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 65 | -------------------------------------------------------------------------------- /.github/workflows/supported.yml: -------------------------------------------------------------------------------- 1 | name: MRI Non-EOL 2 | 3 | env: 4 | K_SOUP_COV_DO: false 5 | 6 | on: 7 | push: 8 | branches: 9 | - 'main' 10 | tags: 11 | - '!*' # Do not execute on tags 12 | pull_request: 13 | branches: 14 | - '*' 15 | # Allow manually triggering the workflow. 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | # Cancels all previous workflow runs for the same branch that have not yet completed. 22 | concurrency: 23 | # The concurrency group contains the workflow name and the branch name. 24 | group: "${{ github.workflow }}-${{ github.ref }}" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | test: 29 | name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | runs-on: ubuntu-latest 32 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | strategy: 36 | matrix: 37 | include: 38 | # Ruby 3.1 39 | - ruby: "ruby-3.1" 40 | appraisal: "ar-7-2" 41 | exec_cmd: "rake spec:orm:active_record" 42 | gemfile: "Appraisal.root" 43 | rubygems: latest 44 | bundler: latest 45 | 46 | # Ruby 3.2 47 | - ruby: "ruby-3.2" 48 | appraisal: "ar-8-0" 49 | exec_cmd: "rake spec:orm:active_record" 50 | gemfile: "Appraisal.root" 51 | rubygems: latest 52 | bundler: latest 53 | 54 | # Ruby 3.3 55 | - ruby: "ruby-3.3" 56 | appraisal: "ar-8-0" 57 | exec_cmd: "rake spec:orm:active_record" 58 | gemfile: "Appraisal.root" 59 | rubygems: latest 60 | bundler: latest 61 | 62 | steps: 63 | - name: Checkout 64 | uses: actions/checkout@v4 65 | 66 | - name: Setup Ruby & RubyGems 67 | uses: ruby/setup-ruby@v1 68 | with: 69 | ruby-version: ${{ matrix.ruby }} 70 | rubygems: ${{ matrix.rubygems }} 71 | bundler: ${{ matrix.bundler }} 72 | bundler-cache: false 73 | 74 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 75 | # We need to do this first to get appraisal installed. 76 | # NOTE: This does not use the main Gemfile at all. 77 | - name: Install Root Appraisal 78 | run: bundle 79 | - name: Appraisal for ${{ matrix.ruby }} ${{ matrix.appraisal }} 80 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 81 | - name: Tests for ${{ matrix.ruby }} ${{ matrix.appraisal }} via ${{ matrix.exec_cmd }} 82 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 83 | -------------------------------------------------------------------------------- /.github/workflows/unsupported.yml: -------------------------------------------------------------------------------- 1 | name: MRI 2.6 & 2.7 (EOL) 2 | 3 | env: 4 | K_SOUP_COV_DO: false 5 | 6 | on: 7 | push: 8 | branches: 9 | - 'main' 10 | tags: 11 | - '!*' # Do not execute on tags 12 | pull_request: 13 | branches: 14 | - '*' 15 | # Allow manually triggering the workflow. 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | # Cancels all previous workflow runs for the same branch that have not yet completed. 22 | concurrency: 23 | # The concurrency group contains the workflow name and the branch name. 24 | group: "${{ github.workflow }}-${{ github.ref }}" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | test: 29 | name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} 30 | if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" 31 | runs-on: ubuntu-22.04 32 | continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} 33 | env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps 34 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile 35 | strategy: 36 | fail-fast: false 37 | matrix: 38 | include: 39 | # Ruby 2.6 40 | - ruby: "ruby-2.6" 41 | appraisal: "ar-6-1" 42 | exec_cmd: "rake spec:orm:active_record" 43 | gemfile: "Appraisal.root" 44 | rubygems: '3.4.22' 45 | bundler: '2.4.22' 46 | 47 | # Ruby 2.7 48 | - ruby: "ruby-2.7" 49 | appraisal: "ar-7-1" 50 | exec_cmd: "rake spec:orm:active_record" 51 | gemfile: "Appraisal.root" 52 | rubygems: '3.4.22' 53 | bundler: '2.4.22' 54 | 55 | steps: 56 | - name: Checkout 57 | uses: actions/checkout@v4 58 | 59 | - name: Setup Ruby & RubyGems 60 | uses: ruby/setup-ruby@v1 61 | with: 62 | ruby-version: ${{ matrix.ruby }} 63 | rubygems: ${{ matrix.rubygems }} 64 | bundler: ${{ matrix.bundler }} 65 | bundler-cache: false 66 | 67 | # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) 68 | # We need to do this first to get appraisal installed. 69 | # NOTE: This does not use the main Gemfile at all. 70 | - name: Install Root Appraisal 71 | run: bundle 72 | - name: Appraisal for ${{ matrix.appraisal }} 73 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle 74 | - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} 75 | run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Artifacts 2 | /pkg/ 3 | /tmp/ 4 | *.gem 5 | 6 | # Bundler 7 | /.bundle/ 8 | /gemfiles/*.lock 9 | /gemfiles/.bundle/ 10 | /gemfiles/.bundle/config 11 | /gemfiles/vendor/ 12 | Appraisal.*.gemfile.lock 13 | 14 | # Specs 15 | .rspec_status 16 | /coverage/ 17 | /spec/reports/ 18 | 19 | # Documentation 20 | /.yardoc/ 21 | /_yardoc/ 22 | /rdoc/ 23 | /doc/ 24 | 25 | # Ruby Version Managers (RVM, rbenv, etc) 26 | # Ignored because we currently use .tool-versions 27 | .rvmrc 28 | .ruby-version 29 | .ruby-gemset 30 | 31 | # Benchmarking 32 | /measurement/ 33 | 34 | # Debugger detritus 35 | .byebug_history 36 | 37 | # direnv - brew install direnv 38 | .env.local 39 | 40 | # OS Detritus 41 | .DS_Store 42 | 43 | # Editors 44 | *~ 45 | 46 | # Test Service Dependencies 47 | /rethinkdb_data 48 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | # CodeStream ignored files 10 | /codestream.xml 11 | -------------------------------------------------------------------------------- /.idea/GitLink.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/active-tab-highlighter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/developer-tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/git_toolbox_blame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/git_toolbox_prj.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | --format=documentation 3 | --colour 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_gem: 2 | rubocop-lts: config/rubygem_rspec.yml 3 | 4 | require: 5 | - 'rubocop-minitest' 6 | - 'rubocop-sequel' 7 | 8 | Sequel/SaveChanges: 9 | Enabled: false 10 | 11 | Lint/UselessMethodDefinition: 12 | Enabled: false 13 | 14 | RSpec/SpecFilePathFormat: 15 | Include: 16 | - spec 17 | - spec_orms 18 | 19 | RSpec/BeforeAfterAll: 20 | Enabled: false 21 | -------------------------------------------------------------------------------- /.simplecov: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "kettle/soup/cover/config" 4 | 5 | SimpleCov.start do 6 | add_filter "/rethinkdb_data/" 7 | add_filter "lib/omniauth/identity/models/nobrainer.rb" 8 | end 9 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 3.4.4 2 | -------------------------------------------------------------------------------- /.yard_gfm_support.rb: -------------------------------------------------------------------------------- 1 | # Gratefully and liberally taken from the MIT-licensed https://github.com/bensheldon/good_job/pull/113/files 2 | require "kramdown" 3 | require "kramdown-parser-gfm" 4 | 5 | # Custom markup provider class that always renders Kramdown using GFM (Github Flavored Markdown). 6 | # GFM is needed to render markdown tables and fenced code blocks in the README. 7 | class KramdownGfmDocument < Kramdown::Document 8 | def initialize(source, options = {}) 9 | options[:input] = "GFM" unless options.key?(:input) 10 | super(source, options) 11 | end 12 | end 13 | 14 | # Insert the new provider as the highest priority option for Markdown. 15 | # See: 16 | # - https://github.com/lsegal/yard/issues/1157 17 | # - https://github.com/lsegal/yard/issues/1017 18 | # - https://github.com/lsegal/yard/blob/main/lib/yard/templates/helpers/markup_helper.rb 19 | YARD::Templates::Helpers::MarkupHelper::MARKUP_PROVIDERS[:markdown].insert( 20 | 0, 21 | {const: "KramdownGfmDocument"}, 22 | ) 23 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --plugin junk 2 | --plugin relative_markdown_links 3 | --readme README.md 4 | --charset utf-8 5 | --markup markdown 6 | --output docs 7 | --load .yard_gfm_support.rb 8 | 'lib/**/*.rb' 9 | - 10 | '*.md' 11 | '*.txt' -------------------------------------------------------------------------------- /Appraisal.root.gemfile: -------------------------------------------------------------------------------- 1 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 2 | 3 | source "https://rubygems.org" 4 | 5 | # Appraisal Root Gemfile is for running appraisal to generate the Appraisal Gemfiles 6 | # in gemfiles/*gemfile. 7 | # On CI, we use it for the Appraisal-based builds. 8 | # We do not load the standard Gemfile, as it is tailored for local development. 9 | 10 | gemspec 11 | 12 | gem "appraisal", github: "pboling/appraisal", branch: "galtzo" 13 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: OmniAuth::Identity 3 | message: >- 4 | If you use this work and you want to cite it, 5 | then you can use the metadata from this file. 6 | type: software 7 | authors: 8 | - given-names: Peter Hurn 9 | family-names: Boling 10 | email: peter@railsbling.com 11 | affiliation: railsbling.com 12 | orcid: 'https://orcid.org/0009-0008-8519-441X' 13 | identifiers: 14 | - type: url 15 | value: 'https://github.com/omniauth/omniauth-identity/' 16 | description: OmniAuth::Identity 17 | repository-code: 'https://github.com/omniauth/omniauth-identity/' 18 | abstract: >- 19 | OmniAuth::Identity 20 | license: See license file 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | [INSERT CONTACT METHOD]. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 127 | at [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | #### IMPORTANT ####################################################### 4 | # Gemfile is for local development ONLY; Gemfile is NOT loaded in CI # 5 | ####################################################### IMPORTANT #### 6 | 7 | source "https://rubygems.org" 8 | 9 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 10 | 11 | gemspec 12 | 13 | ### Std Lib Extracted Gems 14 | gem "mutex_m", "~> 0.2" 15 | gem "stringio", "~> 3.1", ">= 3.1.2" 16 | 17 | ### Security Audit 18 | eval_gemfile "gemfiles/modular/audit.gemfile" 19 | 20 | ### Documentation 21 | eval_gemfile "gemfiles/modular/documentation.gemfile" 22 | 23 | ### Linting 24 | eval_gemfile "gemfiles/modular/style.gemfile" 25 | 26 | ### ORMs 27 | gem "couch_potato", "~> 1.17", require: false 28 | gem "mongoid", ">= 7", require: false 29 | gem "mongoid-rspec", "~> 4.2", require: false 30 | gem "nobrainer", "~> 0.44", require: false 31 | gem "sequel", "~> 5.86", require: false 32 | gem "sqlite3", ">= 1", require: false 33 | 34 | ### Local dev tools 35 | gem "growl" 36 | gem "guard" 37 | gem "guard-bundler" 38 | gem "guard-rspec" 39 | gem "rb-fsevent" 40 | 41 | # Code Coverage 42 | eval_gemfile "gemfiles/modular/coverage.gemfile" 43 | 44 | ### Testing 45 | gem "appraisal", github: "pboling/appraisal", branch: "galtzo" 46 | gem "test-unit", ">= 3.0" 47 | 48 | platform :mri do 49 | ### Debugging (MRI Only) 50 | gem "byebug", ">= 11" 51 | end 52 | 53 | # TODO: Remove this once fixed in upstream bson (> 5.0.2) 54 | # Fix that is only needed on systems with GCC v15+ 55 | # See: https://github.com/mongodb/bson-ruby/pull/355 56 | gem "bson", github: "pboling/bson-ruby", branch: "master" 57 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | guard "rspec", version: 2 do 4 | watch(%r{^spec/.+_spec\.rb$}) 5 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 6 | watch("spec/spec_helper.rb") { "spec" } 7 | end 8 | 9 | guard "bundler" do 10 | watch("Gemfile") 11 | watch(/^.+\.gemspec/) 12 | end 13 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021, 2024 - 2025 Peter H. Boling, and OmniAuth::Identity Contributors 4 | Copyright (c) 2020 Peter H. Boling, Andrew Roberts, and Jellybooks Ltd. 5 | Copyright (c) 2010-2015 Michael Bleigh, and Intridea, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | "Software"), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | 5 | defaults = [] 6 | 7 | # See: https://docs.gitlab.com/ci/variables/predefined_variables/ 8 | is_gitlab = ENV.fetch("GITLAB_CI", "false").casecmp("true") == 0 9 | 10 | ### DEVELOPMENT TASKS 11 | # Setup Kettle Soup Cover 12 | begin 13 | require "kettle-soup-cover" 14 | 15 | Kettle::Soup::Cover.install_tasks 16 | # NOTE: Coverage on CI is configured independent of this task. 17 | # This task is for local development, as it opens results in browser 18 | defaults << "coverage" unless Kettle::Soup::Cover::IS_CI 19 | rescue LoadError 20 | desc("(stub) coverage is unavailable") 21 | task("coverage") do 22 | warn("NOTE: kettle-soup-cover isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 23 | end 24 | end 25 | 26 | # Setup Bundle Audit 27 | begin 28 | require "bundler/audit/task" 29 | 30 | Bundler::Audit::Task.new 31 | defaults.push("bundle:audit:update", "bundle:audit") 32 | rescue LoadError 33 | desc("(stub) bundle:audit is unavailable") 34 | task("bundle:audit") do 35 | warn("NOTE: bundler-audit isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 36 | end 37 | desc("(stub) bundle:audit:update is unavailable") 38 | task("bundle:audit:update") do 39 | warn("NOTE: bundler-audit isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 40 | end 41 | end 42 | 43 | begin 44 | require "rspec/core/rake_task" 45 | 46 | # Define a default test task which will run only specs which work on sqlite3 because, 47 | # when running sqlite3-based tests you don't need any additional services running. 48 | %w(active_record sequel).each do |orm| 49 | RSpec::Core::RakeTask.new("test") do |task| 50 | task.pattern = "{spec/**/*,spec_orms/active_record,spec_orms/sequel}_spec.rb" 51 | end 52 | end 53 | 54 | ### Combo Test Tasks for Continuous Integration 55 | # Define a task for each ORM which will run all ORM-agnostic specs + the specs for a specific ORM. 56 | # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. 57 | %w(active_record couch_potato mongoid sequel).each do |orm| 58 | RSpec::Core::RakeTask.new("spec:orm:#{orm}") do |task| 59 | task.pattern = "{spec/**/*,spec_orms/#{orm}}_spec.rb" 60 | end 61 | end 62 | ### Combo Test Task for Code Coverage Workflow in Continuous Integration 63 | # Requires all services (CouchDB, and MongoDB) to be running. 64 | # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. 65 | RSpec::Core::RakeTask.new("spec:orm:all") do |task| 66 | task.pattern = "{spec,spec_orms}/**/*_spec.rb" 67 | end 68 | 69 | ### Combo Test Tasks for local development... 70 | # Define tasks which only run the ORM-specific tests in isolation 71 | active_record = RSpec::Core::RakeTask.new(:spec_orm_active_record) 72 | active_record.pattern = "spec_orms/active_record_spec.rb" 73 | couch_potato = RSpec::Core::RakeTask.new(:spec_orm_couch_potato) 74 | couch_potato.pattern = "spec_orms/couch_potato_spec.rb" 75 | mongoid = RSpec::Core::RakeTask.new(:spec_orm_mongoid) 76 | mongoid.pattern = "spec_orms/mongoid_spec.rb" 77 | sequel = RSpec::Core::RakeTask.new(:spec_orm_sequel) 78 | sequel.pattern = "spec_orms/sequel_spec.rb" 79 | 80 | # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. 81 | nobrainer = RSpec::Core::RakeTask.new(:spec_orm_nobrainer) 82 | nobrainer.pattern = "spec_ignored/nobrainer_spec.rb" 83 | 84 | # When running all tests you must have CouchDB, and MongoDB running. See README.md 85 | task(spec: %i[ 86 | test 87 | spec_orm_active_record 88 | spec_orm_couch_potato 89 | spec_orm_mongoid 90 | spec_orm_sequel 91 | ]) 92 | rescue LoadError 93 | desc("spec task stub") 94 | task(:spec) do 95 | warn("NOTE: rspec isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 96 | end 97 | end 98 | 99 | # Setup RuboCop-LTS 100 | begin 101 | require "rubocop/lts" 102 | 103 | Rubocop::Lts.install_tasks 104 | # Make autocorrect the default rubocop task 105 | defaults << "rubocop_gradual:autocorrect" 106 | rescue LoadError 107 | desc("(stub) rubocop_gradual is unavailable") 108 | task(:rubocop_gradual) do 109 | warn("NOTE: rubocop-lts isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 110 | end 111 | end 112 | 113 | # Setup Yard 114 | begin 115 | require "yard" 116 | 117 | YARD::Rake::YardocTask.new(:yard) do |t| 118 | t.files = [ 119 | # Source Splats (alphabetical) 120 | "lib/**/*.rb", 121 | "-", # source and extra docs are separated by "-" 122 | # Extra Files (alphabetical) 123 | "*.cff", 124 | "*.md", 125 | "*.txt", 126 | ] 127 | end 128 | defaults << "yard" 129 | rescue LoadError 130 | desc("(stub) yard is unavailable") 131 | task(:yard) do 132 | warn("NOTE: yard isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 133 | end 134 | end 135 | 136 | # Setup Reek 137 | begin 138 | require "reek/rake/task" 139 | 140 | Reek::Rake::Task.new do |t| 141 | t.fail_on_error = true 142 | t.verbose = false 143 | t.source_files = "{lib,spec,spec_ignored,spec_orms}/**/*.rb" 144 | end 145 | defaults << "reek" unless is_gitlab 146 | rescue LoadError 147 | desc("(stub) reek is unavailable") 148 | task(:reek) do 149 | warn("NOTE: reek isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 150 | end 151 | end 152 | 153 | ### RELEASE TASKS 154 | # Setup stone_checksums 155 | begin 156 | require "stone_checksums" 157 | 158 | GemChecksums.install_tasks 159 | rescue LoadError 160 | desc("(stub) build:generate_checksums is unavailable") 161 | task("build:generate_checksums") do 162 | warn("NOTE: stone_checksums isn't installed, or is disabled for #{RUBY_VERSION} in the current environment") 163 | end 164 | end 165 | 166 | task default: defaults 167 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | |---------|-----------| 7 | | 3.1.x | ✅ | 8 | | 3.0.x | ❌ | 9 | | 2.x | ❌ | 10 | | 1.x | ❌ | 11 | | 0.x | ❌ | 12 | 13 | ## Security contact information 14 | 15 | To report a security vulnerability, please use the 16 | [Tidelift security contact](https://tidelift.com/security). 17 | Tidelift will coordinate the fix and disclosure. 18 | 19 | ## Additional Support 20 | 21 | If you are interested in support for versions older than the latest release, 22 | please consider sponsoring the project / maintainer @ https://liberapay.com/pboling/donate, 23 | or find other sponsorship links in the [README]. 24 | 25 | [README]: README.md 26 | 27 | ## Enterprise Support 28 | 29 | Available as part of the Tidelift Subscription. 30 | 31 | The maintainers of this library and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.][tidelift-ref] 32 | 33 | [tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-omniauth-identity?utm_source=rubygems-omniauth-identity&utm_medium=referral&utm_campaign=enterprise&utm_term=repo -------------------------------------------------------------------------------- /bin/_guard-core: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application '_guard-core' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("guard", "_guard-core") 28 | -------------------------------------------------------------------------------- /bin/appraisal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'appraisal' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("appraisal", "appraisal") 28 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN) 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/o 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../Gemfile", __dir__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/o 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || 66 | cli_arg_version || 67 | bundler_requirement_for(lockfile_version) 68 | end 69 | 70 | def bundler_requirement_for(version) 71 | return "#{Gem::Requirement.default}.a" unless version 72 | 73 | bundler_gem_version = Gem::Version.new(version) 74 | 75 | bundler_gem_version.approximate_recommendation 76 | end 77 | 78 | def load_bundler! 79 | ENV["BUNDLE_GEMFILE"] ||= gemfile 80 | 81 | activate_bundler 82 | end 83 | 84 | def activate_bundler 85 | gem_error = activation_error_handling do 86 | gem("bundler", bundler_requirement) 87 | end 88 | return if gem_error.nil? 89 | require_error = activation_error_handling do 90 | require "bundler/version" 91 | end 92 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 93 | warn("Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`") 94 | exit(42) 95 | end 96 | 97 | def activation_error_handling 98 | yield 99 | nil 100 | rescue StandardError, LoadError => e 101 | e 102 | end 103 | end 104 | 105 | m.load_bundler! 106 | 107 | if m.invoked_as_script? 108 | load Gem.bin_path("bundler", "bundle") 109 | end 110 | -------------------------------------------------------------------------------- /bin/bundle-audit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle-audit' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("bundler-audit", "bundle-audit") 28 | -------------------------------------------------------------------------------- /bin/bundler-audit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundler-audit' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("bundler-audit", "bundler-audit") 28 | -------------------------------------------------------------------------------- /bin/byebug: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'byebug' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("byebug", "byebug") 28 | -------------------------------------------------------------------------------- /bin/code_climate_reek: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'code_climate_reek' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("reek", "code_climate_reek") 28 | -------------------------------------------------------------------------------- /bin/coderay: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'coderay' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("coderay", "coderay") 28 | -------------------------------------------------------------------------------- /bin/gem_checksums: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'gem_checksums' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("stone_checksums", "gem_checksums") 28 | -------------------------------------------------------------------------------- /bin/github-markup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'github-markup' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("github-markup", "github-markup") 28 | -------------------------------------------------------------------------------- /bin/guard: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'guard' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("guard", "guard") 28 | -------------------------------------------------------------------------------- /bin/htmldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'htmldiff' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("diff-lcs", "htmldiff") 28 | -------------------------------------------------------------------------------- /bin/httpclient: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'httpclient' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("httpclient", "httpclient") 28 | -------------------------------------------------------------------------------- /bin/ldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'ldiff' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("diff-lcs", "ldiff") 28 | -------------------------------------------------------------------------------- /bin/listen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'listen' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("listen", "listen") 28 | -------------------------------------------------------------------------------- /bin/mongo_console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'mongo_console' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("mongo", "mongo_console") 28 | -------------------------------------------------------------------------------- /bin/pry: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'pry' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("pry", "pry") 28 | -------------------------------------------------------------------------------- /bin/racc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'racc' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("racc", "racc") 28 | -------------------------------------------------------------------------------- /bin/rackup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rackup' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rack", "rackup") 28 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rake' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rake", "rake") 28 | -------------------------------------------------------------------------------- /bin/rdoc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rdoc' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rdoc", "rdoc") 28 | -------------------------------------------------------------------------------- /bin/redcarpet: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'redcarpet' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("redcarpet", "redcarpet") 28 | -------------------------------------------------------------------------------- /bin/reek: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'reek' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("reek", "reek") 28 | -------------------------------------------------------------------------------- /bin/ri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'ri' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rdoc", "ri") 28 | -------------------------------------------------------------------------------- /bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rspec' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rspec-core", "rspec") 28 | -------------------------------------------------------------------------------- /bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rubocop' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rubocop", "rubocop") 28 | -------------------------------------------------------------------------------- /bin/rubocop-gradual: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rubocop-gradual' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("rubocop-gradual", "rubocop-gradual") 28 | -------------------------------------------------------------------------------- /bin/ruby-parse: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'ruby-parse' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("parser", "ruby-parse") 28 | -------------------------------------------------------------------------------- /bin/ruby-rewrite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'ruby-rewrite' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("parser", "ruby-rewrite") 28 | -------------------------------------------------------------------------------- /bin/sequel: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'sequel' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("sequel", "sequel") 28 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /bin/standardrb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'standardrb' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("standard", "standardrb") 28 | -------------------------------------------------------------------------------- /bin/test-unit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'test-unit' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("test-unit", "test-unit") 28 | -------------------------------------------------------------------------------- /bin/thor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'thor' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("thor", "thor") 28 | -------------------------------------------------------------------------------- /bin/yard: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'yard' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("yard", "yard") 28 | -------------------------------------------------------------------------------- /bin/yard-junk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'yard-junk' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("yard-junk", "yard-junk") 28 | -------------------------------------------------------------------------------- /bin/yardoc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'yardoc' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("yard", "yardoc") 28 | -------------------------------------------------------------------------------- /bin/yri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'yri' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 12 | 13 | bundle_binstub = File.expand_path("bundle", __dir__) 14 | 15 | if File.file?(bundle_binstub) 16 | if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") 17 | load(bundle_binstub) 18 | else 19 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 20 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 21 | end 22 | end 23 | 24 | require "rubygems" 25 | require "bundler/setup" 26 | 27 | load Gem.bin_path("yard", "yri") 28 | -------------------------------------------------------------------------------- /certs/pboling.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl 3 | ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW 4 | A2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM 5 | DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy 6 | LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA 7 | uoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61 8 | LRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5 9 | mZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN 10 | coEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV 11 | FMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj 12 | yGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1 13 | to/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD 14 | qbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj 15 | fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ 16 | HlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG 17 | A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD 18 | ggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9 19 | wmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR 20 | L8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm 21 | GUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k 22 | kNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq 23 | QekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA 24 | 0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p 25 | DVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt 26 | L9nRqA== 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.0.gem.sha256: -------------------------------------------------------------------------------- 1 | f9535e116644eed4f67eece3ecb6faa2e1bd5a9665dcd743909e5f77fcd2eae5 -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.0.gem.sha512: -------------------------------------------------------------------------------- 1 | b35c6230931b5773cc62d26170ec0b41a152edf1317f749df00ab579c7ec0b831173dbe236208aef2841878a3efa6d77265a2c132c7c7136370a14dbc695f456 -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.1.gem.sha256: -------------------------------------------------------------------------------- 1 | 67466afa99c5d77f145ada9c417096fe8dc7b34a49f761c99a1aaf2a75284272 -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.1.gem.sha512: -------------------------------------------------------------------------------- 1 | 7ff8385d8355b8c7744fabb5b91067b9fe45e3ca10ca507b5dd6b27f03e2c9ecac2cceacf9707a1a41553e5d6df7544fe8680356134223b06732f2003c0cec77 -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.2.gem.sha256: -------------------------------------------------------------------------------- 1 | 312f54a716ed75469853fb8250f5fb711445131b95f1285db172cf8720089407 -------------------------------------------------------------------------------- /checksums/omniauth-identity-3.1.2.gem.sha512: -------------------------------------------------------------------------------- 1 | 30bdf3083a2b43ff6335d5a7deb475feef98ac3a0fcdbcc0648fb98f2900aa484fb8c2056267f11df335459f114934800d2147b4e3840eb06f7c97fb045f1ad0 -------------------------------------------------------------------------------- /docs/OmniAuth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity.rb,
82 | lib/omniauth/identity/model.rb,
lib/omniauth/identity/version.rb,
lib/omniauth/strategies/identity.rb,
lib/omniauth/identity/models/sequel.rb,
lib/omniauth/identity/models/mongoid.rb,
lib/omniauth/identity/secure_password.rb,
lib/omniauth/identity/models/nobrainer.rb,
lib/omniauth/identity/models/couch_potato.rb,
lib/omniauth/identity/models/active_record.rb
83 |
84 |
85 | 86 |
87 | 88 |

Defined Under Namespace

89 |

90 | 91 | 92 | Modules: Identity, Strategies 93 | 94 | 95 | 96 | 97 |

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 | 114 | 115 |
116 | 117 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity.rb,
82 | lib/omniauth/identity/model.rb,
lib/omniauth/identity/version.rb,
lib/omniauth/identity/models/sequel.rb,
lib/omniauth/identity/models/mongoid.rb,
lib/omniauth/identity/secure_password.rb,
lib/omniauth/identity/models/nobrainer.rb,
lib/omniauth/identity/models/couch_potato.rb,
lib/omniauth/identity/models/active_record.rb
83 |
84 |
85 | 86 |
87 | 88 |

Defined Under Namespace

89 |

90 | 91 | 92 | Modules: Model, Models, SecurePassword, Version 93 | 94 | 95 | 96 | 97 |

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 | 114 | 115 |
116 | 117 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity/Model/ClassCreateApi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity::Model::ClassCreateApi 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity::Model::ClassCreateApi 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity/model.rb
82 |
83 | 84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |

95 | Instance Method Summary 96 | collapse 97 |

98 | 99 | 125 | 126 | 127 | 128 | 129 |
130 |

Instance Method Details

131 | 132 | 133 |
134 |

135 | 136 | #create(*_args) ⇒ Model 137 | 138 | 139 | 140 | 141 | 142 |

143 |
144 |
Deprecated.

v4.0 will begin using #new with #save instead.

145 |
146 |
147 | This method is abstract. 148 |
149 |
150 |
151 |

Persists a new Identity object to the ORM.
152 | Only included if the class doesn’t define create, as a reminder to define create.
153 | Override as needed per ORM.

154 | 155 | 156 |
157 |
158 |
159 |

Parameters:

160 |
    161 | 162 |
  • 163 | 164 | _args 165 | 166 | 167 | (Hash) 168 | 169 | 170 | 171 | — 172 |

    Attributes of the new instance.

    173 |
    174 | 175 |
  • 176 | 177 |
178 | 179 |

Returns:

180 |
    181 | 182 |
  • 183 | 184 | 185 | (Model) 186 | 187 | 188 | 189 | — 190 |

    An instance of the identity model class.

    191 |
    192 | 193 |
  • 194 | 195 |
196 |

Raises:

197 |
    198 | 199 |
  • 200 | 201 | 202 | (NotImplementedError) 203 | 204 | 205 | 206 |
  • 207 | 208 |
209 |

Since:

210 |
    211 | 212 |
  • 213 | 214 | 215 | 216 | 217 | 218 |

    3.0.5

    219 |
    220 | 221 |
  • 222 | 223 |
224 | 225 |
226 | 227 | 235 | 242 | 243 |
228 |
229 | 
230 | 
231 | 79
232 | 80
233 | 81
234 |
236 |
# File 'lib/omniauth/identity/model.rb', line 79
237 | 
238 | def create(*_args)
239 |   raise NotImplementedError
240 | end
241 |
244 |
245 | 246 |
247 | 248 |
249 | 250 | 255 | 256 |
257 | 258 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity/Model/InstancePersistedApi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity::Model::InstancePersistedApi 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity::Model::InstancePersistedApi 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity/model.rb
82 |
83 | 84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |

95 | Instance Method Summary 96 | collapse 97 |

98 | 99 | 125 | 126 | 127 | 128 | 129 |
130 |

Instance Method Details

131 | 132 | 133 |
134 |

135 | 136 | #persisted?true or false 137 | 138 | 139 | 140 | 141 | 142 |

143 |
144 |
145 | This method is abstract. 146 |
147 |
148 |
149 |

Checks if the Identity object is persisted in the ORM.
150 | Default raises an error. Override as needed per ORM.

151 | 152 | 153 |
154 |
155 |
156 | 157 |

Returns:

158 |
    159 | 160 |
  • 161 | 162 | 163 | (true or false) 164 | 165 | 166 | 167 | — 168 |

    true if object exists, false if not.

    169 |
    170 | 171 |
  • 172 | 173 |
174 |

Raises:

175 |
    176 | 177 |
  • 178 | 179 | 180 | (NotImplementedError) 181 | 182 | 183 | 184 |
  • 185 | 186 |
187 |

Since:

188 |
    189 | 190 |
  • 191 | 192 | 193 | 194 | 195 | 196 |

    3.0.5

    197 |
    198 | 199 |
  • 200 | 201 |
202 | 203 |
204 | 205 | 213 | 220 | 221 |
206 |
207 | 
208 | 
209 | 105
210 | 106
211 | 107
212 |
214 |
# File 'lib/omniauth/identity/model.rb', line 105
215 | 
216 | def persisted?
217 |   raise NotImplementedError
218 | end
219 |
222 |
223 | 224 |
225 | 226 |
227 | 228 | 233 | 234 |
235 | 236 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity/Model/InstanceSaveApi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity::Model::InstanceSaveApi 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity::Model::InstanceSaveApi 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity/model.rb
82 |
83 | 84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |

95 | Instance Method Summary 96 | collapse 97 |

98 | 99 | 125 | 126 | 127 | 128 | 129 |
130 |

Instance Method Details

131 | 132 | 133 |
134 |

135 | 136 | #save(**_options, &_block) ⇒ Model 137 | 138 | 139 | 140 | 141 | 142 |

143 |
144 |
145 | This method is abstract. 146 |
147 |
148 |
149 |

Persists a new Identity object to the ORM.
150 | Default raises an error. Override as needed per ORM.
151 | This base version’s arguments are modeled after ActiveModel
152 | since it is a pattern many ORMs follow

153 | 154 | 155 |
156 |
157 |
158 | 159 |

Returns:

160 |
    161 | 162 |
  • 163 | 164 | 165 | (Model) 166 | 167 | 168 | 169 | — 170 |

    An instance of the identity model class.

    171 |
    172 | 173 |
  • 174 | 175 |
176 |

Raises:

177 |
    178 | 179 |
  • 180 | 181 | 182 | (NotImplementedError) 183 | 184 | 185 | 186 |
  • 187 | 188 |
189 |

Since:

190 |
    191 | 192 |
  • 193 | 194 | 195 | 196 | 197 | 198 |

    3.0.5

    199 |
    200 | 201 |
  • 202 | 203 |
204 | 205 |
206 | 207 | 215 | 222 | 223 |
208 |
209 | 
210 | 
211 | 93
212 | 94
213 | 95
214 |
216 |
# File 'lib/omniauth/identity/model.rb', line 93
217 | 
218 | def save(**_options, &_block)
219 |   raise NotImplementedError
220 | end
221 |
224 |
225 | 226 |
227 | 228 |
229 | 230 | 235 | 236 |
237 | 238 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity/Models.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity::Models 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity::Models 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity.rb,
82 | lib/omniauth/identity/models/sequel.rb,
lib/omniauth/identity/models/mongoid.rb,
lib/omniauth/identity/models/nobrainer.rb,
lib/omniauth/identity/models/couch_potato.rb,
lib/omniauth/identity/models/active_record.rb
83 |
84 |
85 | 86 |
87 | 88 |

Defined Under Namespace

89 |

90 | 91 | 92 | Modules: CouchPotatoModule, Mongoid, NoBrainer, Sequel 93 | 94 | 95 | 96 | Classes: ActiveRecord 97 | 98 | 99 |

100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
110 | 111 | 116 | 117 |
118 | 119 | -------------------------------------------------------------------------------- /docs/OmniAuth/Identity/Version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Identity::Version 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Identity::Version 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity/version.rb
82 |
83 | 84 |
85 | 86 | 87 | 88 |

89 | Constant Summary 90 | collapse 91 |

92 | 93 |
94 | 95 |
VERSION = 96 | 97 |
98 |
"3.1.2"
99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
112 | 113 | 118 | 119 |
120 | 121 | -------------------------------------------------------------------------------- /docs/OmniAuth/Strategies.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: OmniAuth::Strategies 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: OmniAuth::Strategies 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
Defined in:
81 |
lib/omniauth/identity.rb,
82 | lib/omniauth/strategies/identity.rb
83 |
84 |
85 | 86 |
87 | 88 |

Defined Under Namespace

89 |

90 | 91 | 92 | 93 | 94 | Classes: Identity 95 | 96 | 97 |

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 | 114 | 115 |
116 | 117 | -------------------------------------------------------------------------------- /docs/css/common.css: -------------------------------------------------------------------------------- 1 | /* Override this file with custom rules */ -------------------------------------------------------------------------------- /docs/css/full_list.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 4 | font-size: 13px; 5 | height: 101%; 6 | overflow-x: hidden; 7 | background: #fafafa; 8 | } 9 | 10 | h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } 11 | .clear { clear: both; } 12 | .fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } 13 | #search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } 14 | #content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } 15 | #full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } 16 | #full_list ul { padding: 0; } 17 | #full_list li { padding: 0; margin: 0; list-style: none; } 18 | #full_list li .item { padding: 5px 5px 5px 12px; } 19 | #noresults { padding: 7px 12px; background: #fff; } 20 | #content.insearch #noresults { margin-left: 7px; } 21 | li.collapsed ul { display: none; } 22 | li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } 23 | li.collapsed a.toggle { cursor: default; background-position: top left; } 24 | li { color: #666; cursor: pointer; } 25 | li.deprecated { text-decoration: line-through; font-style: italic; } 26 | li.odd { background: #f0f0f0; } 27 | li.even { background: #fafafa; } 28 | .item:hover { background: #ddd; } 29 | li small:before { content: "("; } 30 | li small:after { content: ")"; } 31 | li small.search_info { display: none; } 32 | a, a:visited { text-decoration: none; color: #05a; } 33 | li.clicked > .item { background: #05a; color: #ccc; } 34 | li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } 35 | li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } 36 | li.collapsed.clicked a.toggle { background-position: top right; } 37 | #search input { border: 1px solid #bbb; border-radius: 3px; } 38 | #full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } 39 | #full_list_nav a, #nav a:visited { color: #358; } 40 | #full_list_nav a:hover { background: transparent; color: #5af; } 41 | #full_list_nav span:after { content: ' | '; } 42 | #full_list_nav span:last-child:after { content: ''; } 43 | 44 | #content h1 { margin-top: 0; } 45 | li { white-space: nowrap; cursor: normal; } 46 | li small { display: block; font-size: 0.8em; } 47 | li small:before { content: ""; } 48 | li small:after { content: ""; } 49 | li small.search_info { display: none; } 50 | #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #666; padding-left: 0; padding-right: 24px; } 51 | #content.insearch #search { background-position: center right; } 52 | #search input { width: 110px; } 53 | 54 | #full_list.insearch ul { display: block; } 55 | #full_list.insearch .item { display: none; } 56 | #full_list.insearch .found { display: block; padding-left: 11px !important; } 57 | #full_list.insearch li a.toggle { display: none; } 58 | #full_list.insearch li small.search_info { display: block; } 59 | -------------------------------------------------------------------------------- /docs/file.CITATION.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: CITATION 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |

cff-version: 1.2.0
61 | title: OmniAuth::Identity
62 | message: >-
63 | If you use this work and you want to cite it,
64 | then you can use the metadata from this file.
65 | type: software
66 | authors:

67 |
    68 |
  • given-names: Peter Hurn
    69 | family-names: Boling
    70 | email: peter@railsbling.com
    71 | affiliation: railsbling.com
    72 | orcid: ‘https://orcid.org/0009-0008-8519-441X’
    73 | identifiers:
  • 74 |
  • type: url
    75 | value: ‘https://github.com/omniauth/omniauth-identity/’
    76 | description: OmniAuth::Identity
    77 | repository-code: ‘https://github.com/omniauth/omniauth-identity/’
    78 | abstract: >-
    79 | OmniAuth::Identity
    80 | license: See license file
  • 81 |
82 |
83 | 84 | 89 | 90 |
91 | 92 | -------------------------------------------------------------------------------- /docs/file.LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: LICENSE 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |
MIT License

Copyright (c) 2021, 2024 - 2025 Peter H. Boling, and OmniAuth::Identity Contributors
Copyright (c) 2020 Peter H. Boling, Andrew Roberts, and Jellybooks Ltd.
Copyright (c) 2010-2015 Michael Bleigh, and Intridea, Inc.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61 | 62 | 67 | 68 |
69 | 70 | -------------------------------------------------------------------------------- /docs/file.SECURITY.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: SECURITY 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |

Security Policy

61 | 62 |

Supported Versions

63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
VersionSupported
3.1.x
3.0.x
2.x
1.x
0.x
94 | 95 |

Security contact information

96 | 97 |

To report a security vulnerability, please use the
98 | Tidelift security contact.
99 | Tidelift will coordinate the fix and disclosure.

100 | 101 |

Additional Support

102 | 103 |

If you are interested in support for versions older than the latest release,
104 | please consider sponsoring the project / maintainer @ https://liberapay.com/pboling/donate,
105 | or find other sponsorship links in the README.

106 | 107 |

Enterprise Support

108 | 109 |

Available as part of the Tidelift Subscription.

110 | 111 |

The maintainers of this library and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. Learn more.

112 | 113 |
114 | 115 | 120 | 121 |
122 | 123 | -------------------------------------------------------------------------------- /docs/file_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | File List 19 | 20 | 21 | 22 |
23 |
24 |

File List

25 |
26 | 27 | 28 | Classes 29 | 30 | 31 | 32 | Methods 33 | 34 | 35 | 36 | Files 37 | 38 | 39 |
40 | 41 | 45 |
46 | 47 | 87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation by YARD 0.9.37 6 | 7 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /docs/top-level-namespace.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Top Level Namespace 8 | 9 | — Documentation by YARD 0.9.37 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Top Level Namespace 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 |

Defined Under Namespace

82 |

83 | 84 | 85 | Modules: OmniAuth 86 | 87 | 88 | 89 | 90 |

91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | 107 | 108 |
109 | 110 | -------------------------------------------------------------------------------- /gemfiles/ar_5_2.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 5.2.8.1" 7 | gem "mutex_m", "~> 0.1" 8 | gem "stringio", ">= 0.0.2" 9 | gem "sqlite3", "~> 1.3" 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/ar_6_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 6.0.6.1" 7 | gem "mutex_m", "~> 0.2" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", "~> 1.4" 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/ar_6_1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 6.1.7.10" 7 | gem "mutex_m", "~> 0.1" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", "~> 1.4", platforms: [:ruby] 10 | 11 | platforms :jruby do 12 | gem "activerecord-jdbc-adapter", "~> 61.0" 13 | gem "activerecord-jdbcsqlite3-adapter", "~> 61.0" 14 | end 15 | 16 | gemspec path: "../" 17 | -------------------------------------------------------------------------------- /gemfiles/ar_7_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 7.0.8.6" 7 | gem "mutex_m", "~> 0.2" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", "~> 1.4" 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/ar_7_1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 7.1.5" 7 | gem "mutex_m", "~> 0.2" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", "~> 1.5", platforms: [:ruby] 10 | 11 | platforms :jruby do 12 | gem "activerecord-jdbc-adapter", "~> 71.0" 13 | gem "activerecord-jdbcsqlite3-adapter", "~> 71.0" 14 | end 15 | 16 | gemspec path: "../" 17 | -------------------------------------------------------------------------------- /gemfiles/ar_7_2.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 7.2.2" 7 | gem "mutex_m", "~> 0.2" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", "~> 1.6", platforms: [:ruby] 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/ar_8_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "activerecord", "~> 8.0.0" 7 | gem "mutex_m", "~> 0.2" 8 | gem "stringio", "~> 3.0" 9 | gem "sqlite3", ">= 1.7", platforms: [:ruby] 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/audit.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "mutex_m", "~> 0.2" 6 | gem "stringio", "~> 3.0" 7 | 8 | gemspec path: "../" 9 | 10 | eval_gemfile("modular/audit.gemfile") 11 | -------------------------------------------------------------------------------- /gemfiles/couch_1.17.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "couch_potato", "~> 1.17" 7 | gem "mutex_m", "~> 0.1" 8 | gem "sqlite3", ">= 1" 9 | gem "stringio", ">= 0.0.2" 10 | gem "ostruct", "~> 0.1" 11 | 12 | gemspec path: "../" 13 | -------------------------------------------------------------------------------- /gemfiles/couch_1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "couch_potato", "~> 1" 6 | 7 | gemspec path: "../" 8 | -------------------------------------------------------------------------------- /gemfiles/coverage.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "activerecord", "~> 8.0.0" 6 | gem "couch_potato", "~> 1.17" 7 | gem "sequel", "~> 5.86", ">= 5.86.0" 8 | gem "mongoid", "~> 9.0", ">= 9.0.3" 9 | gem "mongoid-rspec", "~> 4.2" 10 | gem "mutex_m", "~> 0.2" 11 | gem "ostruct", "~> 0.1" 12 | gem "stringio", "~> 3.0" 13 | gem "sqlite3", ">= 1.7" 14 | 15 | gemspec path: "../" 16 | 17 | eval_gemfile("modular/coverage.gemfile") 18 | -------------------------------------------------------------------------------- /gemfiles/modular/audit.gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Many gems are dropping support for Ruby < 3, 4 | # so we only want to run our security audit in CI on Ruby 3+ 5 | gem "bundler-audit", "~> 0.9.2" 6 | -------------------------------------------------------------------------------- /gemfiles/modular/coverage.gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # We run code coverage on the latest version of Ruby only. 4 | 5 | # Coverage 6 | gem "kettle-soup-cover", "~> 1.0", ">= 1.0.6", require: false 7 | -------------------------------------------------------------------------------- /gemfiles/modular/documentation.gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Documentation 4 | gem "kramdown", "~> 2.5", ">= 2.5.1" # Ruby >= 2.5 5 | gem "kramdown-parser-gfm", "~> 1.1" # Ruby >= 2.3 6 | gem "yard", "~> 0.9", ">= 0.9.37", require: false 7 | gem "yard-junk", "~> 0.0", ">= 0.0.10", github: "pboling/yard-junk", branch: "next", require: false 8 | gem "yard-relative_markdown_links", "~> 0.5.0" 9 | 10 | # Std Lib extractions 11 | gem "rdoc", "~> 6.11" 12 | -------------------------------------------------------------------------------- /gemfiles/modular/style.gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # We run rubocop on the latest version of Ruby, 4 | # but in support of the oldest supported version of Ruby 5 | 6 | gem "reek" 7 | gem "rubocop-lts", "~> 12.1", ">= 12.1.1" 8 | gem "rubocop-minitest" 9 | gem "rubocop-packaging", "~> 0.5", ">= 0.5.2" 10 | gem "rubocop-rspec", "~> 3.2" 11 | gem "rubocop-sequel" 12 | gem "standard", ">= 1.35.1", "!= 1.41.1", "!= 1.42.0" 13 | 14 | # Std Lib extractions 15 | gem "benchmark", "~> 0.4" # Removed from Std Lib in Ruby 3.5 16 | -------------------------------------------------------------------------------- /gemfiles/mongoid_7.3.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "mongoid", "~> 7.3", ">= 7.3.5" 7 | gem "mongoid-rspec", "~> 4.1" 8 | gem "mutex_m", "~> 0.1" 9 | gem "sqlite3", ">= 1" 10 | gem "stringio", ">= 0.0.2" 11 | 12 | gemspec path: "../" 13 | -------------------------------------------------------------------------------- /gemfiles/mongoid_7.4.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "mongoid", "~> 7.4", ">= 7.4.3" 7 | gem "mongoid-rspec", "~> 4.1" 8 | gem "mutex_m", "~> 0.2" 9 | gem "sqlite3", ">= 1" 10 | gem "stringio", "~> 3.0" 11 | 12 | gemspec path: "../" 13 | -------------------------------------------------------------------------------- /gemfiles/mongoid_8.1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "mongoid", "~> 8.1", ">= 8.1.7" 7 | gem "mongoid-rspec", "~> 4.2" 8 | gem "mutex_m", "~> 0.2" 9 | gem "sqlite3", ">= 1" 10 | gem "stringio", "~> 3.0" 11 | 12 | gemspec path: "../" 13 | -------------------------------------------------------------------------------- /gemfiles/mongoid_9.0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "mongoid", "~> 9.0", ">= 9.0.3" 7 | gem "mongoid-rspec", "~> 4.2" 8 | gem "mutex_m", "~> 0.2" 9 | gem "sqlite3", ">= 1" 10 | gem "stringio", "~> 3.1", ">= 3.1.2" 11 | gem "ostruct", "~> 0.1" 12 | 13 | gemspec path: "../" 14 | -------------------------------------------------------------------------------- /gemfiles/sequel_5.86.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal", branch: "galtzo", git: "https://github.com/pboling/appraisal" 6 | gem "sequel", "~> 5.86", ">= 5.86.0" 7 | gem "mutex_m", "~> 0.1" 8 | gem "stringio", ">= 0.0.2" 9 | gem "sqlite3", ">= 1" 10 | 11 | gemspec path: "../" 12 | -------------------------------------------------------------------------------- /gemfiles/style.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "mutex_m", "~> 0.2" 6 | gem "stringio", "~> 3.0" 7 | 8 | gemspec path: "../" 9 | 10 | eval_gemfile("modular/style.gemfile") 11 | -------------------------------------------------------------------------------- /lib/omniauth-identity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # external gems 4 | require "version_gem" 5 | 6 | # this library's version 7 | require "omniauth/identity/version" 8 | 9 | # Ensure version is configured before loading the rest of the library 10 | OmniAuth::Identity::Version.class_eval do 11 | extend VersionGem::Basic 12 | end 13 | 14 | # this library 15 | require "omniauth/identity" 16 | -------------------------------------------------------------------------------- /lib/omniauth/identity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # TODO[v4]: Remove this deprecation with v4 release. 4 | unless defined?(OmniAuth::Identity::Version::VERSION) 5 | # external gems 6 | require "version_gem" 7 | 8 | # this library's version 9 | require "omniauth/identity/version" 10 | 11 | # Ensure version is configured before loading the rest of the library 12 | OmniAuth::Identity::Version.class_eval do 13 | extend VersionGem::Basic 14 | end 15 | 16 | warn "[DEPRECATION][omniauth-identity v3.1] Change `require 'omniauth/identity'` to `require 'omniauth-identity'`. Support for `require 'omniauth/identity'` will be removed in v4." 17 | end 18 | 19 | require "omniauth" 20 | 21 | module OmniAuth 22 | module Strategies 23 | autoload :Identity, "omniauth/strategies/identity" 24 | end 25 | 26 | module Identity 27 | autoload :Model, "omniauth/identity/model" 28 | autoload :SecurePassword, "omniauth/identity/secure_password" 29 | module Models 30 | autoload :ActiveRecord, "omniauth/identity/models/active_record" 31 | autoload :Mongoid, "omniauth/identity/models/mongoid" 32 | autoload :CouchPotatoModule, "omniauth/identity/models/couch_potato" 33 | autoload :NoBrainer, "omniauth/identity/models/nobrainer" 34 | autoload :Sequel, "omniauth/identity/models/sequel" 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/omniauth/identity/models/active_record.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "active_record" 4 | 5 | module OmniAuth 6 | module Identity 7 | module Models 8 | # ActiveRecord is an ORM for MySQL, PostgreSQL, and SQLite3: 9 | # https://guides.rubyonrails.org/active_record_basics.html 10 | # NOTE: ActiveRecord is based on ActiveModel. 11 | class ActiveRecord < ::ActiveRecord::Base 12 | include ::OmniAuth::Identity::Model 13 | include ::OmniAuth::Identity::SecurePassword 14 | 15 | self.abstract_class = true 16 | # validations: true (default) incurs a dependency on ActiveModel, but ActiveRecord is ActiveModel based. 17 | has_secure_password 18 | 19 | def self.auth_key=(key) 20 | super 21 | validates_uniqueness_of(key, case_sensitive: false) 22 | end 23 | 24 | def self.locate(search_hash) 25 | search_hash = search_hash.reverse_merge!("provider" => "identity") if column_names.include?("provider") 26 | where(search_hash).first 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/omniauth/identity/models/couch_potato.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "couch_potato" 4 | 5 | module OmniAuth 6 | module Identity 7 | module Models 8 | # CouchPotato is an ORM adapter for CouchDB: 9 | # https://github.com/langalex/couch_potato 10 | # NOTE: CouchPotato is based on ActiveModel. 11 | # NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule 12 | # NOTE: Includes "Module" in the name for invalid legacy reasons. Rename only with a major version bump. 13 | module CouchPotatoModule 14 | def self.included(base) 15 | base.class_eval do 16 | include(::OmniAuth::Identity::Model) 17 | include(::OmniAuth::Identity::SecurePassword) 18 | 19 | # validations: true (default) incurs a dependency on ActiveModel, but CouchPotato is ActiveModel based. 20 | has_secure_password 21 | 22 | def self.auth_key=(key) 23 | super 24 | validates_uniqueness_of(key, case_sensitive: false) 25 | end 26 | 27 | def self.locate(search_hash) 28 | where(search_hash).first 29 | end 30 | 31 | def save 32 | CouchPotato.database.save_document(self) 33 | end 34 | end 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/omniauth/identity/models/mongoid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "mongoid" 4 | 5 | module OmniAuth 6 | module Identity 7 | module Models 8 | # Mongoid is an ORM adapter for MongoDB: 9 | # https://github.com/mongodb/mongoid 10 | # NOTE: Mongoid is based on ActiveModel. 11 | module Mongoid 12 | def self.included(base) 13 | base.class_eval do 14 | include(::OmniAuth::Identity::Model) 15 | include(::OmniAuth::Identity::SecurePassword) 16 | 17 | # validations: true (default) incurs a dependency on ActiveModel, but Mongoid is ActiveModel based. 18 | has_secure_password 19 | 20 | def self.auth_key=(key) 21 | super 22 | validates_uniqueness_of(key, case_sensitive: false) 23 | end 24 | 25 | def self.locate(search_hash) 26 | where(search_hash).first 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/omniauth/identity/models/nobrainer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "nobrainer" 4 | 5 | module OmniAuth 6 | module Identity 7 | module Models 8 | # NoBrainer is an ORM adapter for RethinkDB: 9 | # http://nobrainer.io/ 10 | # NOTE: NoBrainer is based on ActiveModel. 11 | module NoBrainer 12 | def self.included(base) 13 | base.class_eval do 14 | include(::OmniAuth::Identity::Model) 15 | include(::OmniAuth::Identity::SecurePassword) 16 | 17 | # validations: true (default) incurs a dependency on ActiveModel, but NoBrainer is ActiveModel based. 18 | has_secure_password 19 | 20 | def self.auth_key=(key) 21 | super 22 | validates_uniqueness_of(key, case_sensitive: false) 23 | end 24 | 25 | def self.locate(search_hash) 26 | where(search_hash).first 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/omniauth/identity/models/sequel.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "sequel" 4 | 5 | module OmniAuth 6 | module Identity 7 | module Models 8 | # Sequel is an ORM adapter for the following databases: 9 | # ADO, Amalgalite, IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle, PostgreSQL, SQLAnywhere, SQLite3, and TinyTDS 10 | # The homepage is: http://sequel.jeremyevans.net/ 11 | # NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted?`: 12 | # * create 13 | # * save 14 | module Sequel 15 | def self.included(base) 16 | base.class_eval do 17 | # NOTE: Using the deprecated :validations_class_methods because it defines 18 | # validates_confirmation_of, while current :validation_helpers does not. 19 | # plugin :validation_helpers 20 | plugin(:validation_class_methods) 21 | 22 | include(::OmniAuth::Identity::Model) 23 | include(::OmniAuth::Identity::SecurePassword) 24 | 25 | # `validations: true` (default) would normally incur a dependency on ActiveModel. 26 | # Starting in v3.1 we check if ActiveModel is defined before we actually set validations. 27 | # If ActiveModel isn't defined, it may be unexpected that validations are not being set, 28 | # so this will result in a warning deprecation until release of v4, 29 | # at which point the default (for Sequel ORM only) will change to `validations: false` 30 | has_secure_password(validations: OmniAuth::Identity::Version.major < 4) 31 | 32 | class << self 33 | def auth_key=(key) 34 | super 35 | # Sequel version of validates_uniqueness_of! Does not incur ActiveRecord dependency! 36 | validates_uniqueness_of(:key, case_sensitive: false) 37 | end 38 | 39 | # @param arguments [any] - 40 | # Filtering is probably the most common dataset modifying action done in Sequel. 41 | # Both the where and filter methods filter the dataset by modifying the dataset’s WHERE clause. 42 | # Both accept a wide variety of input formats, which are passed as arguments below. 43 | # See: https://sequel.jeremyevans.net/rdoc/files/doc/querying_rdoc.html#label-Filters 44 | def locate(arguments) 45 | where(arguments).first 46 | end 47 | end 48 | 49 | def persisted? 50 | exists? 51 | end 52 | 53 | def save 54 | super 55 | end 56 | end 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /lib/omniauth/identity/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module OmniAuth 4 | module Identity 5 | module Version 6 | VERSION = "3.1.2" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/omniauth/strategies/identity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module OmniAuth 4 | module Strategies 5 | # The identity strategy allows you to provide simple internal 6 | # user authentication using the same process flow that you 7 | # use for external OmniAuth providers. 8 | class Identity 9 | DEFAULT_REGISTRATION_FIELDS = %i[password password_confirmation].freeze 10 | include OmniAuth::Strategy 11 | option :fields, %i[name email] 12 | 13 | # Primary Feature Switches: 14 | option :enable_registration, true # See #other_phase and #request_phase 15 | option :enable_login, true # See #other_phase 16 | 17 | # Customization Options: 18 | option :on_login, nil # See #request_phase 19 | option :on_validation, nil # See #registration_phase 20 | option :on_registration, nil # See #registration_phase 21 | option :on_failed_registration, nil # See #registration_phase 22 | option :locate_conditions, ->(req) { {model.auth_key => req.params["auth_key"]} } 23 | option :create_identity_link_text, "Create an Identity" 24 | option :registration_failure_message, "One or more fields were invalid" 25 | option :validation_failure_message, "Validation failed" 26 | option :title, "Identity Verification" # Title for Login Form 27 | option :registration_form_title, "Register Identity" # Title for Registration Form 28 | 29 | def request_phase 30 | if options[:on_login] 31 | options[:on_login].call(env) 32 | else 33 | build_omniauth_login_form.to_response 34 | end 35 | end 36 | 37 | def callback_phase 38 | return fail!(:invalid_credentials) unless identity 39 | 40 | super 41 | end 42 | 43 | def other_phase 44 | if options[:enable_registration] && on_registration_path? 45 | if request.get? 46 | registration_form 47 | elsif request.post? 48 | registration_phase 49 | else 50 | call_app! 51 | end 52 | elsif options[:enable_login] && on_request_path? 53 | # OmniAuth, by default, disables "GET" requests for security reasons. 54 | # This effectively disables omniauth-identity tool's login form feature. 55 | # Because it is disabled by default, and because enabling it would desecuritize all the other 56 | # OmniAuth strategies that may be implemented, we do not ask users to modify that setting. 57 | # Instead we hook in here in the "other_phase", with a config setting of our own: `enable_login` 58 | request_phase 59 | else 60 | call_app! 61 | end 62 | end 63 | 64 | def registration_form(validation_message = nil) 65 | if options[:on_registration] 66 | options[:on_registration].call(env) 67 | else 68 | build_omniauth_registration_form(validation_message).to_response 69 | end 70 | end 71 | 72 | def registration_phase 73 | attributes = (options[:fields] + DEFAULT_REGISTRATION_FIELDS).each_with_object({}) do |k, h| 74 | h[k] = request.params[k.to_s] 75 | end 76 | if model.respond_to?(:column_names) && model.column_names.include?("provider") 77 | attributes.reverse_merge!(provider: "identity") 78 | end 79 | if validating? 80 | @identity = model.new(attributes) 81 | env["omniauth.identity"] = @identity 82 | if valid? 83 | @identity.save 84 | registration_result 85 | else 86 | registration_failure(options[:validation_failure_message]) 87 | end 88 | else 89 | @identity = model.create(attributes) 90 | env["omniauth.identity"] = @identity 91 | registration_result 92 | end 93 | end 94 | 95 | uid { identity.uid } 96 | info { identity.info } 97 | 98 | def registration_path 99 | options[:registration_path] || "#{script_name}#{path_prefix}/#{name}/register" 100 | end 101 | 102 | def on_registration_path? 103 | on_path?(registration_path) 104 | end 105 | 106 | def identity 107 | conditions = options[:locate_conditions] 108 | conditions = conditions.is_a?(Proc) ? instance_exec(request, &conditions).to_hash : conditions.to_hash 109 | 110 | @identity ||= model.authenticate(conditions, request.params["password"]) 111 | end 112 | 113 | def model 114 | options[:model] || ::Identity 115 | end 116 | 117 | private 118 | 119 | def build_omniauth_login_form 120 | OmniAuth::Form.build( 121 | title: options[:title], 122 | url: callback_path, 123 | ) do |f| 124 | f.text_field("Login", "auth_key") 125 | f.password_field("Password", "password") 126 | if options[:enable_registration] 127 | f.html("

#{options[:create_identity_link_text]}

") 128 | end 129 | end 130 | end 131 | 132 | def build_omniauth_registration_form(validation_message) 133 | OmniAuth::Form.build(title: options[:registration_form_title]) do |f| 134 | f.html("

#{validation_message}

") if validation_message 135 | options[:fields].each do |field| 136 | f.text_field(field.to_s.capitalize, field.to_s) 137 | end 138 | f.password_field("Password", "password") 139 | f.password_field("Confirm Password", "password_confirmation") 140 | end 141 | end 142 | 143 | # Validates the model before it is persisted 144 | # 145 | # @return [truthy or falsey] :on_validation option is truthy or falsey 146 | def validating? 147 | !!options[:on_validation] 148 | end 149 | 150 | # Validates the model before it is persisted 151 | # 152 | # @return [true or false] result of :on_validation call 153 | def valid? 154 | # on_validation may run a Captcha or other validation mechanism 155 | # Must return true when validation passes, false otherwise 156 | !!options[:on_validation].call(env: env) 157 | end 158 | 159 | def registration_failure(message) 160 | if options[:on_failed_registration] 161 | options[:on_failed_registration].call(env) 162 | else 163 | registration_form(message) 164 | end 165 | end 166 | 167 | def registration_result 168 | if @identity.persisted? 169 | env["PATH_INFO"] = "#{path_prefix}/#{name}/callback" 170 | callback_phase 171 | else 172 | registration_failure(options[:registration_failure_message]) 173 | end 174 | end 175 | end 176 | end 177 | end 178 | -------------------------------------------------------------------------------- /omniauth-identity.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem_version = 4 | if RUBY_VERSION >= "3.1" 5 | # Loading version into an anonymous module allows version.rb to get code coverage from SimpleCov! 6 | # See: https://github.com/simplecov-ruby/simplecov/issues/557#issuecomment-2630782358 7 | Module.new.tap { |mod| Kernel.load("lib/omniauth/identity/version.rb", mod) }::OmniAuth::Identity::Version::VERSION 8 | else 9 | # TODO: Remove this hack once support for Ruby 3.0 and below is removed 10 | Kernel.load("lib/omniauth/identity/version.rb") 11 | g_ver = OmniAuth::Identity::Version::VERSION 12 | OmniAuth::Identity::Version.send(:remove_const, :VERSION) 13 | g_ver 14 | end 15 | 16 | Gem::Specification.new do |spec| 17 | spec.name = "omniauth-identity" 18 | spec.version = gem_version 19 | spec.authors = ["Peter Boling", "Andrew Roberts", "Michael Bleigh"] 20 | spec.email = ["peter.boling@gmail.com"] 21 | 22 | # Linux distros often package gems and securely certify them independent 23 | # of the official RubyGem certification process. Allowed via ENV["SKIP_GEM_SIGNING"] 24 | # Ref: https://gitlab.com/oauth-xx/version_gem/-/issues/3 25 | # Hence, only enable signing if `SKIP_GEM_SIGNING` is not set in ENV. 26 | # See CONTRIBUTING.md 27 | unless ENV.include?("SKIP_GEM_SIGNING") 28 | user_cert = "certs/#{ENV.fetch("GEM_CERT_USER", ENV["USER"])}.pem" 29 | cert_file_path = File.join(__dir__, user_cert) 30 | cert_chain = cert_file_path.split(",") 31 | cert_chain.select! { |fp| File.exist?(fp) } 32 | if cert_file_path && cert_chain.any? 33 | spec.cert_chain = cert_chain 34 | if $PROGRAM_NAME.end_with?("gem") && ARGV[0] == "build" 35 | spec.signing_key = File.join(Gem.user_home, ".ssh", "gem-private_key.pem") 36 | end 37 | end 38 | end 39 | 40 | spec.summary = "Traditional username/password based authentication system for OmniAuth" 41 | spec.description = spec.summary 42 | spec.homepage = "https://github.com/omniauth/#{spec.name}" 43 | spec.license = "MIT" 44 | spec.required_ruby_version = ">= 2.4" 45 | 46 | spec.metadata["homepage_uri"] = "https://railsbling.com/tags/#{spec.name}/" 47 | spec.metadata["source_code_uri"] = "#{spec.homepage}/tree/v#{spec.version}" 48 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md" 49 | spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues" 50 | spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/#{spec.name}/#{spec.version}" 51 | spec.metadata["wiki_uri"] = "#{spec.homepage}/wiki" 52 | spec.metadata["funding_uri"] = "https://liberapay.com/pboling" 53 | spec.metadata["news_uri"] = "https://www.railsbling.com/tags/#{spec.name}" 54 | spec.metadata["rubygems_mfa_required"] = "true" 55 | 56 | # Specify which files should be added to the gem when it is released. 57 | spec.files = Dir[ 58 | # Splats (alphabetical) 59 | "lib/**/*.rb", 60 | ] 61 | # Automatically included with gem package, no need to list again in files. 62 | spec.extra_rdoc_files = Dir[ 63 | # Files (alphabetical) 64 | "CHANGELOG.md", 65 | "CODE_OF_CONDUCT.md", 66 | "CONTRIBUTING.md", 67 | "LICENSE.txt", 68 | "README.md", 69 | "SECURITY.md", 70 | ] 71 | spec.rdoc_options += [ 72 | "--title", 73 | "#{spec.name} - #{spec.summary}", 74 | "--main", 75 | "CHANGELOG.md", 76 | "CODE_OF_CONDUCT.md", 77 | "CONTRIBUTING.md", 78 | "LICENSE.txt", 79 | "README.md", 80 | "SECURITY.md", 81 | "--line-numbers", 82 | "--inline-source", 83 | "--quiet", 84 | ] 85 | spec.bindir = "exe" 86 | spec.require_paths = ["lib"] 87 | 88 | spec.add_dependency("bcrypt", "~> 3.1") 89 | spec.add_dependency("mutex_m", "~> 0.1") 90 | spec.add_dependency("omniauth", ">= 1") 91 | spec.add_dependency("version_gem", "~> 1.1", ">= 1.1.8") 92 | 93 | ### Testing 94 | spec.add_development_dependency("activerecord", ">= 5") 95 | spec.add_development_dependency("anonymous_active_record", "~> 1.0", ">= 1.0.9") 96 | spec.add_development_dependency("rack-test", "~> 1") 97 | spec.add_development_dependency("rake", "~> 13") 98 | spec.add_development_dependency("rspec", "~> 3") 99 | spec.add_development_dependency("rspec-block_is_expected", "~> 1.0", ">= 1.0.6") 100 | 101 | ### Releasing 102 | spec.add_development_dependency("stone_checksums", "~> 1.0") # ruby >= 2.2 103 | end 104 | -------------------------------------------------------------------------------- /spec/config/byebug.rb: -------------------------------------------------------------------------------- 1 | if VersionGem::Ruby.gte_minimum_version?("2.7") 2 | require "byebug" if ENV.fetch("DEBUG", "false").casecmp?("true") 3 | end 4 | -------------------------------------------------------------------------------- /spec/config/rspec/rack_test.rb: -------------------------------------------------------------------------------- 1 | require "rack/test" 2 | 3 | RSpec.configure do |config| 4 | config.include Rack::Test::Methods 5 | end 6 | -------------------------------------------------------------------------------- /spec/config/rspec/rspec_block_is_expected.rb: -------------------------------------------------------------------------------- 1 | require "rspec/block_is_expected" 2 | require "rspec/block_is_expected/matchers/not" 3 | -------------------------------------------------------------------------------- /spec/config/rspec/rspec_core.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | # Enable flags like --only-failures and --next-failure 3 | config.example_status_persistence_file_path = ".rspec_status" 4 | 5 | # Disable RSpec exposing methods globally on `Module` and `main` 6 | config.disable_monkey_patching! 7 | 8 | config.expect_with :rspec do |c| 9 | c.syntax = :expect 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/config/rspec/version_gem.rb: -------------------------------------------------------------------------------- 1 | require "version_gem/rspec" 2 | -------------------------------------------------------------------------------- /spec/omniauth/identity/model_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe OmniAuth::Identity::Model do 4 | before do 5 | identity_test_klass = Class.new do 6 | include OmniAuth::Identity::Model 7 | end 8 | stub_const("IdentityTestClass", identity_test_klass) 9 | end 10 | 11 | describe "Class Methods" do 12 | subject(:model_klass) { IdentityTestClass } 13 | 14 | include_context "model with class methods" 15 | 16 | describe "::locate" do 17 | it("is abstract") do 18 | expect { model_klass.locate("email" => "example") }.to raise_error(NotImplementedError) 19 | end 20 | end 21 | end 22 | 23 | describe "Instance Methods" do 24 | subject(:instance) { IdentityTestClass.new } 25 | 26 | include_context "instance with instance methods" 27 | 28 | describe "#authenticate" do 29 | it("is abstract") { expect { instance.authenticate("my-password") }.to raise_error(NotImplementedError) } 30 | end 31 | 32 | describe "#auth_key" do 33 | it "raises a NotImplementedError if the auth_key method is not defined" do 34 | expect { instance.auth_key }.to raise_error(NotImplementedError) 35 | end 36 | end 37 | 38 | describe "#auth_key=" do 39 | it "raises a NotImplementedError if the auth_key method is not defined" do 40 | expect { instance.auth_key = "broken" }.to raise_error(NotImplementedError) 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/omniauth/identity/secure_password_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HasTheMethod 4 | def self.has_secure_password 5 | end 6 | end 7 | 8 | class DoesNotHaveTheMethod 9 | end 10 | 11 | RSpec.describe OmniAuth::Identity::SecurePassword do 12 | it "extends with the class methods if it does not have the method" do 13 | expect(DoesNotHaveTheMethod).to receive(:extend).with(OmniAuth::Identity::SecurePassword::ClassMethods) 14 | DoesNotHaveTheMethod.include described_class 15 | end 16 | 17 | it "does not extend if the method is already defined" do 18 | expect(HasTheMethod).not_to receive(:extend) 19 | HasTheMethod.include described_class 20 | end 21 | 22 | it "responds to has_secure_password afterwards" do 23 | [HasTheMethod, DoesNotHaveTheMethod].each do |klass| 24 | klass.send(:include, described_class) 25 | expect(klass).to respond_to(:has_secure_password) 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/omniauth/identity/version_spec.rb: -------------------------------------------------------------------------------- 1 | # rubocop:disable RSpec/SpecFilePathFormat 2 | 3 | RSpec.describe OmniAuth::Identity::Version do 4 | it_behaves_like "a Version module", described_class 5 | 6 | it "is greater than 1.0.0" do 7 | expect(Gem::Version.new(described_class) >= Gem::Version.new("1.0.0")).to be(true) 8 | end 9 | end 10 | 11 | # rubocop:enable RSpec/SpecFilePathFormat 12 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # NOTE: mongoid and no_brainer can't be loaded at the same time. 4 | # If you try it, one or both of them will not work. 5 | # This is why the ORM specs are split into a separate directory and run in separate threads. 6 | 7 | ENV["RUBY_ENV"] = "test" # Used by NoBrainer 8 | ENV["MONGOID_ENV"] = "test" # Used by Mongoid 9 | 10 | # External library dependencies 11 | require "version_gem/ruby" 12 | 13 | # RSpec Configs 14 | require "config/byebug" 15 | require "config/rspec/rack_test" 16 | require "config/rspec/rspec_block_is_expected" 17 | require "config/rspec/rspec_core" 18 | require "config/rspec/version_gem" 19 | 20 | # RSpec Support 21 | spec_root_matcher = %r{#{__dir__}/(.+)\.rb\Z} 22 | Dir.glob(Pathname.new(__dir__).join("support/**/", "*.rb")).each { |f| require f.match(spec_root_matcher)[1] } 23 | 24 | # Test Constants 25 | DEFAULT_PASSWORD = "hang-a-left-at-the-diner" 26 | DEFAULT_EMAIL = "mojo@example.com" 27 | 28 | # Last thing before loading this gem is to set up code coverage 29 | begin 30 | # This does not require "simplecov", but 31 | require "kettle-soup-cover" 32 | # this next line has a side effect of running `.simplecov` 33 | require "simplecov" if defined?(Kettle::Soup::Cover) && Kettle::Soup::Cover::DO_COV 34 | rescue LoadError 35 | nil 36 | end 37 | 38 | # This gem 39 | require "omniauth-identity" 40 | -------------------------------------------------------------------------------- /spec/support/shared_contexts/instance_with_instance_methods.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_examples "instance with instance methods" do 4 | describe "#initialize" do 5 | it "does not raise an error" do 6 | block_is_expected.not_to raise_error 7 | end 8 | end 9 | 10 | describe "#uid" do 11 | it "defaults to #id" do 12 | allow(instance).to receive(:respond_to?).with(:id).and_return(true) 13 | allow(instance).to receive(:id).and_return "wakka-do" 14 | expect(instance.uid).to eq("wakka-do") 15 | end 16 | 17 | it "stringifies it" do 18 | allow(instance).to receive(:id).and_return 123 19 | expect(instance.uid).to eq("123") 20 | end 21 | 22 | it "raises NotImplementedError if #id is not defined" do 23 | allow(instance).to receive(:respond_to?).with(:id).and_return(false) 24 | expect { instance.uid }.to raise_error(NotImplementedError) 25 | end 26 | end 27 | 28 | describe "#auth_key" do 29 | it "defaults to #email" do 30 | allow(instance).to receive(:respond_to?).with(:email).and_return(true) 31 | allow(instance).to receive(:email).and_return("bob@bob.com") 32 | expect(instance.auth_key).to eq("bob@bob.com") 33 | end 34 | 35 | it "uses the class .auth_key" do 36 | instance.class.auth_key "login" 37 | allow(instance).to receive(:login).and_return "bob" 38 | expect(instance.auth_key).to eq("bob") 39 | instance.class.auth_key nil 40 | end 41 | end 42 | 43 | describe "#auth_key=" do 44 | it "defaults to setting email" do 45 | allow(instance).to receive(:respond_to?).with(:email=).and_return(true) 46 | expect(instance).to receive(:email=).with "abc" 47 | 48 | instance.auth_key = "abc" 49 | end 50 | 51 | it "uses a custom .auth_key if one is provided" do 52 | instance.class.auth_key "login" 53 | allow(instance).to receive(:respond_to?).with(:login=).and_return(true) 54 | expect(instance).to receive(:login=).with("abc") 55 | 56 | instance.auth_key = "abc" 57 | end 58 | end 59 | 60 | describe "#info" do 61 | it "includes all attributes as they have been set" do 62 | allow(instance).to receive(:name).and_return("Bob Bobson") 63 | allow(instance).to receive(:nickname).and_return("bob") 64 | 65 | expect(instance.info).to include({ 66 | "name" => "Bob Bobson", 67 | "nickname" => "bob", 68 | }) 69 | end 70 | 71 | it "uses firstname and lastname, over nickname, to set missing name" do 72 | allow(instance).to receive(:first_name).and_return("shoeless") 73 | allow(instance).to receive(:last_name).and_return("joe") 74 | allow(instance).to receive(:nickname).and_return("george") 75 | instance.info["name"] == "shoeless joe" 76 | end 77 | 78 | it "uses nickname to set missing name when first and last are not set" do 79 | allow(instance).to receive(:nickname).and_return("bob") 80 | instance.info["name"] == "bob" 81 | end 82 | 83 | it "does not overwrite a provided name" do 84 | allow(instance).to receive(:name).and_return("Awesome Dude") 85 | allow(instance).to receive(:first_name).and_return("Frank") 86 | expect(instance.info["name"]).to eq("Awesome Dude") 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /spec/support/shared_contexts/model_with_class_methods.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_examples "model with class methods" do 4 | describe "class definition" do 5 | it "does not raise an error" do 6 | block_is_expected.not_to raise_error 7 | end 8 | end 9 | 10 | describe "::authenticate" do 11 | it "calls locate and then authenticate" do 12 | mocked_instance = double("ExampleModel", authenticate: "abbadoo") 13 | args = { 14 | email: "example", 15 | } 16 | allow(model_klass).to receive(:locate).with(args).and_return(mocked_instance) 17 | expect(model_klass.authenticate(args, "pass")).to eq("abbadoo") 18 | end 19 | 20 | it "calls locate with additional scopes when provided" do 21 | mocked_instance = double("ExampleModel", authenticate: "abbadoo") 22 | args = { 23 | email: "example", 24 | user_type: "admin", 25 | } 26 | allow(model_klass).to receive(:locate).with(args).and_return(mocked_instance) 27 | expect(model_klass.authenticate(args, "pass")).to eq("abbadoo") 28 | end 29 | 30 | it "recovers gracefully if locate is nil" do 31 | allow(model_klass).to receive(:locate).and_return(nil) 32 | expect(model_klass.authenticate("blah", "foo")).to be false 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/support/shared_contexts/persistable_model.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_context "persistable model" do 4 | include_context "model with class methods" 5 | 6 | describe "instance methods" do 7 | subject(:instance) { model_klass.new } 8 | 9 | include_context "instance with instance methods" 10 | 11 | before do 12 | instance.email = DEFAULT_EMAIL 13 | instance.password = DEFAULT_PASSWORD 14 | instance.password_confirmation = DEFAULT_PASSWORD 15 | end 16 | 17 | describe "#valid?" do 18 | subject(:is_valid) do 19 | instance.valid? 20 | end 21 | 22 | it "is valid" do 23 | expect(is_valid).to be(true) 24 | end 25 | end 26 | 27 | describe "#save" do 28 | subject(:is_saved) do 29 | instance.save 30 | end 31 | 32 | it "does not raise an error" do 33 | block_is_expected.not_to raise_error 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec_ignored/nobrainer_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 1. While the Ruby driver, nobrainer, is maintained, 4 | # RethinkDB itself is currently a zombie project. 5 | # 2. There are zero examples in the wild of a GitHub Actions workflow 6 | # that sets up a RethinkDB service to test client code against. 7 | # As long as above points remain current, no attempt will be made to get nobrainer specs running in CI, 8 | # unless a RethinkDB-fan wants to take a shot at it. 9 | # You might be inspired by the existing other services this library is currently 10 | # tested against (e.g. CouchDB, MongoDB) 11 | # See: https://github.com/rethinkdb/rethinkdb/issues/6981 12 | # 13 | # NOTE: mongoid and nobrainer can't be loaded at the same time. 14 | # If you try it, one or both of them will not work. 15 | # 16 | # However, if you have RethinkDB installed locally, this spec should work in isolation! 17 | require "nobrainer" 18 | 19 | RSpec.describe(OmniAuth::Identity::Models::NoBrainer, :rethinkdb) do 20 | before(:all) do 21 | NoBrainer.configure do |config| 22 | config.app_name = "DeezBrains" 23 | config.rethinkdb_urls = ["rethinkdb://127.0.0.1:28015/DeezBrains_test"] 24 | config.table_options = { 25 | shards: 1, 26 | replicas: 1, 27 | write_acks: :majority, 28 | } 29 | end 30 | NoBrainer.sync_schema 31 | end 32 | 33 | before do 34 | nobrainer_test_identity = Class.new do 35 | include NoBrainer::Document 36 | include OmniAuth::Identity::Models::NoBrainer 37 | field :email 38 | field :password_digest 39 | end 40 | stub_const("NoBrainerTestIdentity", nobrainer_test_identity) 41 | NoBrainer.purge! 42 | end 43 | 44 | describe "model", type: :model do 45 | subject(:model_klass) { NoBrainerTestIdentity } 46 | 47 | include_context "persistable model" 48 | 49 | describe "::locate" do 50 | it "delegates locate to the where query method" do 51 | args = { 52 | "email" => "open faced", 53 | "category" => "sandwiches", 54 | } 55 | allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) 56 | expect(model_klass.locate(args)).to(eq("wakka")) 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /spec_orms/active_record_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "active_record" 4 | require "anonymous_active_record" 5 | 6 | class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end 7 | 8 | RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, :sqlite3) do 9 | describe "model", type: :model do 10 | subject(:model_klass) do 11 | AnonymousActiveRecord.generate( 12 | parent_klass: "OmniAuth::Identity::Models::ActiveRecord", 13 | columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest], 14 | connection_params: {adapter: is_java ? "jdbcsqlite3" : "sqlite3", encoding: "utf8", database: ":memory:"}, 15 | ) do 16 | auth_key :email 17 | def flower 18 | "🌸" 19 | end 20 | end 21 | end 22 | 23 | let(:is_java) { RUBY_PLATFORM == "java" } 24 | 25 | include_context "persistable model" 26 | 27 | describe "::table_name" do 28 | it "does not use STI rules for its table name" do 29 | expect(TestIdentity.table_name).to(eq("test_identities")) 30 | end 31 | end 32 | 33 | describe "::locate" do 34 | it "delegates locate to the where query method" do 35 | args = { 36 | email: "open faced", 37 | category: "sandwiches", 38 | provider: "identity", 39 | } 40 | allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) 41 | expect(model_klass.locate(args)).to(eq("wakka")) 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec_orms/couch_potato_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "couch_potato" 4 | 5 | RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, :couchdb) do 6 | before(:all) do 7 | CouchPotato::Config.database_host = "http://admin:#{ENV.fetch("COUCHDB_PASSWORD", "password")}@127.0.0.1:5984" 8 | CouchPotato::Config.database_name = "test" 9 | CouchPotato.couchrest_database.recreate! 10 | end 11 | 12 | before do 13 | couch_potato_test_identity = Class.new do 14 | # NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule 15 | include CouchPotato::Persistence 16 | include OmniAuth::Identity::Models::CouchPotatoModule 17 | property :email 18 | property :password_digest 19 | end 20 | stub_const("CouchPotatoTestIdentity", couch_potato_test_identity) 21 | end 22 | 23 | describe "model", type: :model do 24 | subject(:model_klass) { CouchPotatoTestIdentity } 25 | 26 | include_context "persistable model" 27 | 28 | describe "::locate" do 29 | it "delegates to the where query method" do 30 | args = { 31 | "email" => "open faced", 32 | "category" => "sandwiches", 33 | } 34 | allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) 35 | expect(model_klass.locate(args)).to(eq("wakka")) 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /spec_orms/mongoid_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # NOTE: mongoid and no_brainer can't be loaded at the same time. 4 | # If you try it, one or both of them will not work. 5 | require_relative "support/rspec_config/mongoid" 6 | 7 | RSpec.describe(OmniAuth::Identity::Models::Mongoid, :mongodb) do 8 | describe "model", type: :model do 9 | subject(:model_klass) { MongoidTestIdentity } 10 | 11 | it { is_expected.to(be_mongoid_document) } 12 | 13 | it "does not munge collection name" do 14 | expect(subject).to(be_stored_in(database: "db1", collection: "mongoid_test_identities", client: "default")) 15 | end 16 | 17 | include_context "persistable model" 18 | 19 | describe "::locate" do 20 | it "delegates to the where query method" do 21 | args = { 22 | "email" => "open faced", 23 | "category" => "sandwiches", 24 | } 25 | allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) 26 | expect(model_klass.locate(args)).to(eq("wakka")) 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec_orms/sequel_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "sqlite3" 4 | require "sequel" 5 | 6 | DB = Sequel.sqlite 7 | 8 | RSpec.describe(OmniAuth::Identity::Models::Sequel, :sqlite3) do 9 | before(:all) do 10 | # Connect to an in-memory sqlite3 database. 11 | DB.create_table(:sequel_test_identities) do 12 | primary_key :id 13 | String :email, null: false 14 | String :password_digest, null: false 15 | end 16 | end 17 | 18 | before do 19 | sequel_test_identity = Class.new(Sequel::Model(:sequel_test_identities)) do 20 | include OmniAuth::Identity::Models::Sequel 21 | auth_key :email 22 | end 23 | stub_const("SequelTestIdentity", sequel_test_identity) 24 | end 25 | 26 | describe "model", type: :model do 27 | subject(:model_klass) { SequelTestIdentity } 28 | 29 | include_context "persistable model" 30 | 31 | describe "::locate" do 32 | it "delegates to the where query method" do 33 | args = {email: "open faced", category: "sandwiches"} 34 | allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) 35 | expect(model_klass.locate(args)).to(eq("wakka")) 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /spec_orms/support/rspec_config/mongoid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "mongoid" 4 | require "mongoid-rspec" 5 | 6 | RSpec.configure do |config| 7 | config.include(Mongoid::Matchers, mongodb: true) 8 | end 9 | 10 | Mongoid.load!(File.join(__dir__, "mongoid.yml")) 11 | 12 | class MongoidTestIdentity 13 | include ::Mongoid::Document 14 | include ::OmniAuth::Identity::Models::Mongoid 15 | store_in database: "db1", collection: "mongoid_test_identities" 16 | field :email, type: String 17 | field :password_digest, type: String 18 | end 19 | -------------------------------------------------------------------------------- /spec_orms/support/rspec_config/mongoid.yml: -------------------------------------------------------------------------------- 1 | test: 2 | clients: 3 | default: 4 | database: mongoid_test 5 | hosts: 6 | - localhost:27017 7 | options: 8 | server_selection_timeout: 1 9 | --------------------------------------------------------------------------------