Add integration tests for implicit flow
Squashed commits: [d5001fe] Refactor [8d8a23f] Add test for when authorization is denied [659fc56] Adjust password flow integration test
This commit is contained in:
parent
ee9ac06e1a
commit
7b80a7408d
12 changed files with 82 additions and 42 deletions
|
|
@ -4,6 +4,7 @@ class OpenidConnect::Authorization < ActiveRecord::Base
|
|||
|
||||
validates :user, presence: true
|
||||
validates :o_auth_application, presence: true
|
||||
validates :user, uniqueness: {scope: :o_auth_application}
|
||||
|
||||
has_many :scopes, through: :authorization_scopes
|
||||
has_many :o_auth_access_tokens, dependent: :destroy
|
||||
|
|
|
|||
|
|
@ -602,10 +602,6 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def find_authorization_by_client_id(client_id)
|
||||
OpenidConnect::Authorization.find_by_client_id_and_user client_id, self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def clearable_fields
|
||||
|
|
|
|||
|
|
@ -10,8 +10,4 @@ class CreateOAuthApplications < ActiveRecord::Migration
|
|||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :o_auth_applications
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class CreateOAuthAccessTokens < ActiveRecord::Migration
|
||||
def self.up
|
||||
def change
|
||||
create_table :o_auth_access_tokens do |t|
|
||||
t.belongs_to :authorization, index: true
|
||||
t.string :token
|
||||
|
|
|
|||
|
|
@ -4,17 +4,17 @@ Feature: Access protected resources using password flow
|
|||
|
||||
Scenario: Invalid credentials to token endpoint
|
||||
When I register a new client
|
||||
And I send a post request from that client to the token endpoint using invalid credentials
|
||||
And I send a post request from that client to the password flow token endpoint using invalid credentials
|
||||
Then I should receive an "invalid_grant" error
|
||||
|
||||
Scenario: Invalid bearer tokens sent
|
||||
When I register a new client
|
||||
And I send a post request from that client to the token endpoint using "kent"'s credentials
|
||||
And I send a post request from that client to the password flow token endpoint using "kent"'s credentials
|
||||
And I use invalid bearer tokens to access user info
|
||||
Then I should receive an "invalid_token" error
|
||||
|
||||
Scenario: Valid password flow
|
||||
When I register a new client
|
||||
And I send a post request from that client to the token endpoint using "kent"'s credentials
|
||||
And I send a post request from that client to the password flow token endpoint using "kent"'s credentials
|
||||
And I use received valid bearer tokens to access user info
|
||||
Then I should receive "kent"'s id, username, and email
|
||||
|
|
|
|||
26
features/desktop/oidc_implicit_flow.feature
Normal file
26
features/desktop/oidc_implicit_flow.feature
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
@javascript
|
||||
Feature: Access protected resources using implicit flow
|
||||
Background:
|
||||
Given a user with username "kent"
|
||||
And the OpenID scope exists
|
||||
|
||||
Scenario: Invalid client id to auth endpoint
|
||||
When I register a new client
|
||||
And I send a post request from that client to the implicit flow authorization endpoint using a invalid client id
|
||||
And I sign in as "kent@kent.kent"
|
||||
Then I should see an "bad_request" error
|
||||
|
||||
Scenario: Application is denied authorization
|
||||
When I register a new client
|
||||
And I send a post request from that client to the implicit flow authorization endpoint
|
||||
And I sign in as "kent@kent.kent"
|
||||
And I deny authorization to the client
|
||||
Then I should not see any tokens in the redirect url
|
||||
|
||||
Scenario: Application is authorized
|
||||
When I register a new client
|
||||
And I send a post request from that client to the implicit flow authorization endpoint
|
||||
And I sign in as "kent@kent.kent"
|
||||
And I give my consent and authorize the client
|
||||
And I parse the bearer tokens and use it to access user info
|
||||
Then I should receive "kent"'s id, username, and email
|
||||
41
features/step_definitions/implicit_flow_steps.rb
Normal file
41
features/step_definitions/implicit_flow_steps.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
Given(/^the OpenID scope exists$/) do
|
||||
OpenidConnect::Scope.create(name: "openid")
|
||||
end
|
||||
|
||||
Given /^I send a post request from that client to the implicit flow authorization endpoint$/ do
|
||||
client_json = JSON.parse(last_response.body)
|
||||
auth_endpoint_url = "/openid_connect/authorizations/new"
|
||||
visit auth_endpoint_url + "?client_id=" + client_json["o_auth_application"]["client_id"] + "&redirect_uri=" + "http://localhost:3000" +
|
||||
"&response_type=id_token token" + "&scope=openid" + "&nonce=hello" + "&state=hi"
|
||||
end
|
||||
|
||||
Given /^I send a post request from that client to the implicit flow authorization endpoint using a invalid client id/ do
|
||||
auth_endpoint_url = "/openid_connect/authorizations/new"
|
||||
visit auth_endpoint_url + "?client_id=randomid" + "&redirect_uri=" + "http://localhost:3000" +
|
||||
"&response_type=id_token token" + "&scope=openid" + "&nonce=hello" + "&state=hi"
|
||||
end
|
||||
|
||||
When /^I give my consent and authorize the client$/ do
|
||||
click_button "Approve"
|
||||
end
|
||||
|
||||
When /^I deny authorization to the client$/ do
|
||||
click_button "Deny"
|
||||
end
|
||||
|
||||
Then /^I should not see any tokens in the redirect url$/ do
|
||||
access_token = current_url[/(?<=access_token=)[^&]+/]
|
||||
id_token = current_url[/(?<=access_token=)[^&]+/]
|
||||
expect(access_token).to eq(nil)
|
||||
expect(id_token).to eq(nil)
|
||||
end
|
||||
|
||||
When /^I parse the bearer tokens and use it to access user info$/ do
|
||||
access_token = current_url[/(?<=access_token=)[^&]+/]
|
||||
user_info_endpoint_url = "/api/v0/user/"
|
||||
get user_info_endpoint_url, access_token: access_token
|
||||
end
|
||||
|
||||
Then /^I should see an "([^\"]*)" error$/ do |error_message|
|
||||
expect(page).to have_content(error_message)
|
||||
end
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
When /^I register a new client$/ do
|
||||
client_registration_url = "/openid_connect/clients"
|
||||
post client_registration_url, redirect_uris: ["http://localhost:3000"] # Not actually used
|
||||
post client_registration_url, redirect_uris: ["http://localhost:3000"]
|
||||
end
|
||||
|
||||
Given /^I send a post request from that client to the token endpoint using "([^\"]*)"'s credentials$/ do |username|
|
||||
Given /^I send a post request from that client to the password flow token endpoint using "([^\"]*)"'s credentials$/ do |username|
|
||||
client_json = JSON.parse(last_response.body)
|
||||
user = User.find_by(username: username)
|
||||
token_endpoint_url = "/openid_connect/access_tokens"
|
||||
|
|
@ -13,7 +13,7 @@ Given /^I send a post request from that client to the token endpoint using "([^\
|
|||
client_secret: client_json["o_auth_application"]["client_secret"]
|
||||
end
|
||||
|
||||
Given /^I send a post request from that client to the token endpoint using invalid credentials$/ do
|
||||
Given /^I send a post request from that client to the password flow token endpoint using invalid credentials$/ do
|
||||
client_json = JSON.parse(last_response.body)
|
||||
token_endpoint_url = "/openid_connect/access_tokens"
|
||||
post token_endpoint_url, grant_type: "password", username: "bob", password: "wrongpassword",
|
||||
|
|
@ -7,17 +7,17 @@ module OpenidConnect
|
|||
@app = Rack::OAuth2::Server::Token.new do |req, res|
|
||||
o_auth_app = retrieve_client(req)
|
||||
if app_valid?(o_auth_app, req)
|
||||
handle_flows(req, res)
|
||||
handle_flows(o_auth_app, req, res)
|
||||
else
|
||||
req.invalid_client!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_flows(req, res)
|
||||
def handle_flows(o_auth_app, req, res)
|
||||
case req.grant_type
|
||||
when :password
|
||||
handle_password_flow(req, res)
|
||||
handle_password_flow(o_auth_app, req, res)
|
||||
when :refresh_token
|
||||
handle_refresh_flow(req, res)
|
||||
else
|
||||
|
|
@ -25,11 +25,11 @@ module OpenidConnect
|
|||
end
|
||||
end
|
||||
|
||||
def handle_password_flow(req, res)
|
||||
def handle_password_flow(o_auth_app, req, res)
|
||||
user = User.find_for_database_authentication(username: req.username)
|
||||
if user
|
||||
if user.valid_password?(req.password)
|
||||
auth = OpenidConnect::Authorization.find_or_create(req.client_id, user)
|
||||
auth = OpenidConnect::Authorization.find_or_create_by(o_auth_application: o_auth_app, user: user)
|
||||
res.access_token = auth.create_access_token
|
||||
else
|
||||
req.invalid_grant!
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Documentation for v0</title>
|
||||
<link href="v2/style.css" media="screen" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="operations">
|
||||
<h3>API Operations</h3>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Documentation for v0</h1>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
body {margin: 0; background-color: #fff; color: #000; font-family: Arial,sans-serif;}
|
||||
content {margin-left: 200px;}
|
||||
content h1 {text-align: center;}
|
||||
operations {float: left; width: 200px; border-right: 1px solid #ccc;}
|
||||
operations h3 {text-align: center;}
|
||||
|
|
@ -7,6 +7,8 @@ describe OpenidConnect::AuthorizationsController, type: :controller do
|
|||
name: "Diaspora Test Client", redirect_uris: ["http://localhost:3000/", "http://localhost/"])
|
||||
end
|
||||
|
||||
# TODO: jhass - "Might want to setup some factories in spec/factories.rb, see factory_girl's docs."
|
||||
|
||||
before do
|
||||
sign_in :user, alice
|
||||
allow(@controller).to receive(:current_user).and_return(alice)
|
||||
|
|
|
|||
Loading…
Reference in a new issue