Skip to content

Commit

Permalink
Merge 3d2edfa into 99f83eb
Browse files Browse the repository at this point in the history
  • Loading branch information
pboling committed Nov 30, 2023
2 parents 99f83eb + 3d2edfa commit 5022cc8
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 48 deletions.
62 changes: 44 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,61 @@
name: Omniauth JWT Tests

on:
pull_request:
push:
branches:
- master
- main
- 'master'
- 'main'
tags:
- '!*' # Do not execute on tags
pull_request:
branches:
- '*'
# Allow manually triggering the workflow.
workflow_dispatch:

# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
# The concurrency group contains the workflow name and the branch name.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
name: Ruby ${{ matrix.ruby }}
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
strategy:
fail-fast: false
matrix:
ruby: ["2.7", "2.6", "2.5"]
experimental: [false]
rubygems:
- latest
bundler:
- latest
gemfile:
- vanilla
ruby:
- "2.6"
- "2.7"
- "3.0"
- "3.1"
- "3.2"
exclude:
# Vanilla + 3.2 is effectively run by coverage workflow
- gemfile: vanilla
ruby: "3.2"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-ruby@v1
- name: Checkout
uses: actions/checkout@v3
- name: Setup Ruby & Bundle
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: Bundler cache
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-gems-
- name: Setup gems
run: |
gem install bundler
bundle config path vendor/bundle
bundle install --jobs 4
rubygems: ${{ matrix.rubygems }}
bundler: ${{ matrix.bundler }}
bundler-cache: true
- name: Tests
run: bundle exec rspec
91 changes: 91 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Code Coverage

env:
K_SOUP_COV_MIN_BRANCH: 100
K_SOUP_COV_MIN_LINE: 89

on:
push:
branches:
- 'master'
- 'main'
tags:
- '!*' # Do not execute on tags
pull_request:
branches:
- '*'
# Allow manually triggering the workflow.
workflow_dispatch:

# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
# The concurrency group contains the workflow name and the branch name.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Specs with Coverage - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
CI_CODECOV: true
COVER_ALL: true
strategy:
fail-fast: false
matrix:
experimental: [false]
rubygems:
- latest
bundler:
- latest
gemfile:
- coverage
ruby:
- "3.2"

runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Ruby & Bundle
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
rubygems: ${{ matrix.rubygems }}
bundler: ${{ matrix.bundler }}
bundler-cache: true

- name: Run RSpec tests
run: |
bundle exec rspec
- name: Code Coverage Summary Report
uses: irongut/CodeCoverageSummary@v1.3.0
if: ${{ github.event_name == 'pull_request' }}
with:
filename: ./coverage/coverage.xml
badge: true
fail_below_min: true
format: markdown
hide_branch_rate: false
hide_complexity: true
indicators: true
output: both
thresholds: '100 100'
continue-on-error: ${{ matrix.experimental != 'false' }}

- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: ${{ github.event_name == 'pull_request' }}
with:
recreate: true
path: code-coverage-results.md
continue-on-error: ${{ matrix.experimental != 'false' }}

- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: ${{ matrix.experimental != 'false' }}
2 changes: 2 additions & 0 deletions .simplecov
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "kettle/soup/cover/config"
SimpleCov.start # you could do this somewhere else, up to you, but you do have to do it
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ source 'https://rubygems.org'

# Specify your gem's dependencies in omniauth-jwt.gemspec
gemspec

gem 'byebug'
10 changes: 8 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
require "bundler/gem_tasks"

require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)

desc "alias test task to spec"
task test: :spec

RSpec::Core::RakeTask.new
require "kettle-soup-cover"
Kettle::Soup::Cover.install_tasks

task :default => :spec
task default: :spec
5 changes: 4 additions & 1 deletion discourse-omniauth-jwt.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "guard"
spec.add_development_dependency "guard-rspec"
spec.add_development_dependency "rack-test"

spec.add_development_dependency "rack", "~> 3.0"
spec.add_development_dependency "rack-session", "~> 2.0"
spec.add_development_dependency "json"

spec.add_dependency "jwt", "~> 2.2.1"
spec.add_dependency "omniauth", "~> 1.1"
end
12 changes: 12 additions & 0 deletions gemfiles/coverage.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

source "https://rubygems.org"

# Gemfile is only for local development.
# On CI we only need the gemspecs' dependencies (including development dependencies).
# Exceptions, if any, will be found in gemfiles/*
gem "kettle-soup-cover", "~> 1.0", ">= 1.0.2"

gemspec path: "../"
11 changes: 11 additions & 0 deletions gemfiles/style.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

source "https://rubygems.org"

# Gemfile is only for local development.
# On CI we only need the gemspecs' dependencies (including development dependencies).
# Exceptions, if any, will be found in gemfiles/*

gemspec path: "../"
11 changes: 11 additions & 0 deletions gemfiles/vanilla.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

source "https://rubygems.org"

# Gemfile is only for local development.
# On CI we only need the gemspecs' dependencies (including development dependencies).
# Exceptions, if any, will be found in gemfiles/*

gemspec path: "../"
26 changes: 14 additions & 12 deletions lib/omniauth/strategies/jwt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,35 @@ class ClaimInvalid < StandardError; end
class BadJwt < StandardError; end

include OmniAuth::Strategy

args [:secret]

option :secret, nil
option :decode_options, {}
option :jwks_loader
option :algorithm, 'HS256'
option :algorithm, nil
option :decode_options, {}
option :uid_claim, 'email'
option :required_claims, %w(name email)
option :info_map, {"name" => "name", "email" => "email"}
option :auth_url, nil
option :valid_within, nil

def request_phase
redirect options.auth_url
end

def decoded
begin
# JWT.decode can handle either algorithms or algorithm, but not both.
default_algo = options.decode_options.key?(:algorithms) ? nil : options.algorithm || 'HS256'
@decoded ||= ::JWT.decode(
request.params['jwt'],
options.secret,
true,
options.decode_options.merge!(
options.decode_options.merge(
{
algorithm: options.algorithm,
algorithm: default_algo,
jwks: options.jwks_loader
}.compact
)
Expand All @@ -49,29 +51,29 @@ def decoded
raise ClaimInvalid.new("'iat' timestamp claim is too skewed from present.") if options.valid_within && (Time.now.to_i - @decoded["iat"]).abs > options.valid_within
@decoded
end

def callback_phase
super
rescue BadJwt => e
fail! 'bad_jwt', e
rescue ClaimInvalid => e
fail! :claim_invalid, e
end

uid{ decoded[options.uid_claim] }

extra do
{:raw_info => decoded}
end

info do
options.info_map.inject({}) do |h,(k,v)|
h[k.to_s] = decoded[v.to_s]
h
end
end
end

class Jwt < JWT; end
end
end

0 comments on commit 5022cc8

Please sign in to comment.