Add a test for openid connect support
This commit is contained in:
parent
64bcf7652b
commit
1f62a2b342
4 changed files with 96 additions and 10 deletions
1
Gemfile
1
Gemfile
|
@ -149,6 +149,7 @@ group :test do
|
|||
gem "capybara", ">= 2.15"
|
||||
gem "erb_lint", :require => false
|
||||
gem "factory_bot_rails"
|
||||
gem "jwt"
|
||||
gem "minitest", "~> 5.1"
|
||||
gem "puma", "~> 5.6"
|
||||
gem "rails-controller-testing"
|
||||
|
|
|
@ -586,6 +586,7 @@ DEPENDENCIES
|
|||
jbuilder (~> 2.7)
|
||||
jquery-rails
|
||||
json
|
||||
jwt
|
||||
kgio
|
||||
kramdown
|
||||
libxml-ruby (>= 2.0.5)
|
||||
|
|
|
@ -22,3 +22,33 @@ trace_icon_storage: "test"
|
|||
# Lower some rate limits for testing
|
||||
max_changeset_comments_per_hour: 30
|
||||
moderator_changeset_comments_per_hour: 60
|
||||
# Private key for signing id_tokens
|
||||
doorkeeper_signing_key: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDA4pSRHIicerJQ
|
||||
BvIy9lGJ6ZQA7SAGVM8QeNMBaQftS+ROMY+6CFCJ0kiwb9oDdtFNyo3gpgmlULMC
|
||||
q0C96r0UllKnTSkHSntkKM0wy3TX0pa8QBaJbbcOXU13xu5cR7ffvtn2kQX8RZc9
|
||||
eZtE/bSybNBDSiS4mbP31cSQ71EYsbfD3UiWOpOTbc6Xlw9kCkUjwXk36Jnim7gF
|
||||
1kFjD3Vq94ij4OVNxcFp+btrfhq2tsiXa9IPBlt1xTetHwj5HrxseDu2qNQNgPxY
|
||||
ivFAA3t4BuIuou1HjAdzfqp7Ylsr2b7qx+w+Y9TqhH6AcKd0i1qxh6bYnJezH9JU
|
||||
BjlJvJMhAgMBAAECggEAAID2/gldiqRqunkc1n48iJ2CufKPRAT3r3rT+OvNzf8F
|
||||
6csJAuWKVE8ndR0trBb6L/eooYloJWA4aiLes0BIMyQQs4go5HB7hwTw7ZYycsKF
|
||||
i0NS676iHO2odKN2iZN/CvIO1AKH9KM35GdgvPA5XG1FU/pUbeOqNn+pQ5mkaWnt
|
||||
kt+ndBpJQDPSS7nTY8g2BCh97SJSbxEPAccAqNLSvKQED4QVygC63jYZNPDxkJWI
|
||||
guzNn4wv1AfM0DU4W5fI0UtNSxcWSsefWBJTOKO/uQr/XJglxVh6uKof1dnBZiJD
|
||||
KU6/+bR1cXoKQ05HAcEcf/mtjJGwnze41p1EI22gYQKBgQDB+VZJwvxlME1MgEGJ
|
||||
WFPPKiQspKjS0kgbfBw7Iny+mYM6YLpQyF0NFNRloALW2rHH2QLNSerHMlytZUAd
|
||||
1SluQZ4We6P3hLDi2J3p37lkIdBXhjJi8gdoEfQ1YVcCbPGbR2ZVwYms7BP3yiQY
|
||||
ZLcHLUKPKG6hOZztY1gBYqoKqQKBgQD+kBtR8krdJHPEU3m+d/6NWlGk4KZgCFx5
|
||||
ouN/aHtxE6Ge+mUwbrJun/oVrFjbX7ySYTYYb6SdKUrchyKfJL4Z89WHGwrFTV1/
|
||||
6J2ShXmoeUeic1TS4btcnFmZyCXlADk1eyHZm9wtkwd5e2lBfdRxzErKC42lWdaQ
|
||||
rreP2nZHuQKBgQCiNbVgB6vznrn1kIe9qFylsJMBtkzryCe+vEILfaKd7VhdOEh2
|
||||
h6ew6ctYlL/rFoV3H1YFgJvSKp5v7mz4xapY5oyiNpD+yzr06LrdulaZkuFcX//A
|
||||
2K8y61iyTw1pHNvKw6Gjcy6DqgRkwej/cTHR0ZqIhwJE1x4RMnOE7RJPyQKBgQCM
|
||||
SLYFjtSa0b/KbYYl5NKu6xsbFYIaYgE0NwPP7rA4PG1QwwSIkDhcpmSXFQdSvYuZ
|
||||
z2CUTtIUmfDbXs1BjmoEu07syYZB/MSN/I75c/z7TvqfF5ejLyqlerQV/yqC7ICa
|
||||
bGTXGwFXTDNOSyhSIxm0LLT6ayt/9+Y6jU4zRFzyYQKBgGiScevkv/XNz9MXswJ+
|
||||
2bEIJNIJn0wIeuopifcDQrOTeCK+037t1AQ3lxMXisJABwG1jfw7WTjF3zz4dSUX
|
||||
cK1+/2V+OkM/0nXjxPwPj7LiOediUyZNUn48r29uGOL1S83PSUdyST207CP6mZjc
|
||||
K8aJmnGsVEAcWPzbpNh14q/c
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require "test_helper"
|
||||
require "jwt"
|
||||
|
||||
class OAuth2Test < ActionDispatch::IntegrationTest
|
||||
def test_oauth2
|
||||
|
@ -12,7 +13,8 @@ class OAuth2Test < ActionDispatch::IntegrationTest
|
|||
|
||||
token = request_token(client, code)
|
||||
|
||||
test_token(token, user, client)
|
||||
assert_equal "read_prefs", token["scope"]
|
||||
test_token(token["access_token"], user, client)
|
||||
end
|
||||
|
||||
def test_oauth2_oob
|
||||
|
@ -30,7 +32,8 @@ class OAuth2Test < ActionDispatch::IntegrationTest
|
|||
|
||||
token = request_token(client, code)
|
||||
|
||||
test_token(token, user, client)
|
||||
assert_equal "read_prefs", token["scope"]
|
||||
test_token(token["access_token"], user, client)
|
||||
end
|
||||
|
||||
def test_oauth2_pkce_plain
|
||||
|
@ -46,7 +49,8 @@ class OAuth2Test < ActionDispatch::IntegrationTest
|
|||
|
||||
token = request_token(client, code, verifier)
|
||||
|
||||
test_token(token, user, client)
|
||||
assert_equal "read_prefs", token["scope"]
|
||||
test_token(token["access_token"], user, client)
|
||||
end
|
||||
|
||||
def test_oauth2_pkce_s256
|
||||
|
@ -62,16 +66,67 @@ class OAuth2Test < ActionDispatch::IntegrationTest
|
|||
|
||||
token = request_token(client, code, verifier)
|
||||
|
||||
test_token(token, user, client)
|
||||
assert_equal "read_prefs", token["scope"]
|
||||
test_token(token["access_token"], user, client)
|
||||
end
|
||||
|
||||
def test_openid_connect
|
||||
user = create(:user)
|
||||
client = create(:oauth_application, :redirect_uri => "https://some.web.app.example.org/callback", :scopes => "openid read_prefs")
|
||||
state = SecureRandom.urlsafe_base64(16)
|
||||
verifier = SecureRandom.urlsafe_base64(48)
|
||||
challenge = Base64.urlsafe_encode64(Digest::SHA256.digest(verifier), :padding => false)
|
||||
|
||||
authorize_client(user, client, :state => state, :code_challenge => challenge, :code_challenge_method => "S256", :scope => "openid read_prefs")
|
||||
assert_response :redirect
|
||||
code = validate_redirect(client, state)
|
||||
|
||||
token = request_token(client, code, verifier)
|
||||
|
||||
assert_equal "openid read_prefs", token["scope"]
|
||||
|
||||
access_token = token["access_token"]
|
||||
assert_not_nil access_token
|
||||
|
||||
id_token = token["id_token"]
|
||||
assert_not_nil id_token
|
||||
|
||||
data, _headers = JWT.decode id_token, Doorkeeper::OpenidConnect.signing_key.keypair, true, {
|
||||
:algorithm => [Doorkeeper::OpenidConnect.signing_algorithm.to_s],
|
||||
:verify_iss => true,
|
||||
:iss => "#{Settings.server_protocol}://#{Settings.server_url}",
|
||||
:verify_sub => true,
|
||||
:sub => user.id,
|
||||
:verify_aud => true,
|
||||
:aud => client.uid
|
||||
}
|
||||
|
||||
assert_equal user.id.to_s, data["sub"]
|
||||
assert_not data.key?("preferred_username")
|
||||
|
||||
get oauth_userinfo_path
|
||||
assert_response :unauthorized
|
||||
|
||||
auth_header = bearer_authorization_header(access_token)
|
||||
get oauth_userinfo_path, :headers => auth_header
|
||||
assert_response :success
|
||||
|
||||
userinfo = response.parsed_body
|
||||
|
||||
assert_not_nil userinfo
|
||||
assert_equal user.id.to_s, userinfo["sub"]
|
||||
assert_equal user.display_name, userinfo["preferred_username"]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authorize_client(user, client, options = {})
|
||||
options = options.merge(:client_id => client.uid,
|
||||
:redirect_uri => client.redirect_uri,
|
||||
:response_type => "code",
|
||||
:scope => "read_prefs")
|
||||
options = {
|
||||
:client_id => client.uid,
|
||||
:redirect_uri => client.redirect_uri,
|
||||
:response_type => "code",
|
||||
:scope => "read_prefs"
|
||||
}.merge(options)
|
||||
|
||||
get oauth_authorization_path(options)
|
||||
assert_response :redirect
|
||||
|
@ -135,9 +190,8 @@ class OAuth2Test < ActionDispatch::IntegrationTest
|
|||
assert_response :success
|
||||
token = response.parsed_body
|
||||
assert_equal "Bearer", token["token_type"]
|
||||
assert_equal "read_prefs", token["scope"]
|
||||
|
||||
token["access_token"]
|
||||
token
|
||||
end
|
||||
|
||||
def test_token(token, user, client)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue