This repository was archived by the owner on Jan 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
ID Site Authentication #58
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
d11c63f
Create basic workflow for id site authentication
cilim 6ac5748
Validate jwt response from stormpath after login
cilim 3efa73e
Adjust register controller for ID site workflow
cilim 6bbc290
Use variables instead of hardcoded strings in id site jwt payload
cilim 0ab09cc
Use url for cb_uri instead of path
cilim 637f046
DRY up the logout controllers and fix failing specs
cilim 8f53a5b
Refactor building payload and jwt for id site into service object
cilim d1d58a4
Add request and payload builder specs
cilim 659f0b2
Merge branch 'master' into mc-id-site-login
cilim fc7b604
Add login specs after id site authentication
cilim c83a88c
Fix failing travis spec
cilim 5d2b30f
Use ID site auth logic from Ruby SDK and remove the PayloadBuilder
cilim bc53734
Rescue JWT expiration error and display message
cilim 4c3c5fc
Move callback_url generation into method and write specs for token an…
cilim ed60b55
Randomize emails in factories even more
cilim File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ spec/dummy/db/development.sqlite3 | |
spec/dummy/log/development.log | ||
spec/dummy/log/test.log | ||
spec/dummy/tmp | ||
docs |
57 changes: 57 additions & 0 deletions
57
app/controllers/stormpath/rails/id_site_login/new_controller.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
module Stormpath | ||
module Rails | ||
module IdSiteLogin | ||
class NewController < BaseController | ||
before_action :require_no_authentication! | ||
|
||
def call | ||
begin | ||
result = Stormpath::Rails::Client.application.handle_id_site_callback(request.url) | ||
account = Stormpath::Rails::Client.client.accounts.get(result.account_href) | ||
login_the_account(account) | ||
respond_with_success(account) | ||
rescue Stormpath::Error, JWT::VerificationError => error | ||
respond_with_error(error) | ||
end | ||
end | ||
|
||
private | ||
|
||
def login_the_account(account) | ||
AccountLoginWithStormpathToken.new( | ||
cookies, account, | ||
Stormpath::Rails::Client.application, | ||
Stormpath::Rails::Client.client.data_store.api_key | ||
).call | ||
end | ||
|
||
def respond_with_success(account) | ||
respond_to do |format| | ||
format.html { redirect_to login_redirect_route, notice: 'Successfully signed in' } | ||
format.json { render json: AccountSerializer.to_h(account) } | ||
end | ||
end | ||
|
||
def respond_with_error(error) | ||
respond_to do |format| | ||
format.html do | ||
flash.now[:error] = error.message | ||
render stormpath_config.web.login.view | ||
end | ||
format.json do | ||
render json: { message: error.message }, status: error.try(:status) | ||
end | ||
end | ||
end | ||
|
||
def login_redirect_route | ||
if params[:next] | ||
URI(params[:next]).path | ||
else | ||
stormpath_config.web.login.next_uri | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
19 changes: 19 additions & 0 deletions
19
app/controllers/stormpath/rails/id_site_logout/new_controller.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module Stormpath | ||
module Rails | ||
module IdSiteLogout | ||
class NewController < BaseController | ||
def call | ||
TokenAndCookiesCleaner.new(cookies).remove | ||
redirect_to callback_url | ||
end | ||
|
||
private | ||
|
||
def callback_url | ||
Stormpath::Rails::Client.application.create_id_site_url(callback_uri: root_url, | ||
logout: true) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ module Register | |
class NewController < BaseController | ||
def call | ||
if stormpath_config.web.id_site.enabled | ||
redirect_to id_site_register_url | ||
redirect_to callback_url | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would move to a seperate method private
def callback_url
Stormpath::Rails::Client.application.create_id_site_url(
callback_uri: id_site_result_url,
path: Stormpath::Rails.config.web.id_site.login_uri
)
end |
||
elsif signed_in? | ||
redirect_to root_path | ||
else | ||
|
@@ -14,6 +14,15 @@ def call | |
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def callback_url | ||
Stormpath::Rails::Client.application.create_id_site_url( | ||
callback_uri: id_site_result_url, | ||
path: Stormpath::Rails.config.web.id_site.register_uri | ||
) | ||
end | ||
end | ||
end | ||
end | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module Stormpath | ||
module Rails | ||
class TokenAndCookiesCleaner | ||
attr_reader :cookies | ||
|
||
def initialize(cookies) | ||
@cookies = cookies | ||
end | ||
|
||
def remove | ||
delete_tokens | ||
delete_cookies | ||
end | ||
|
||
private | ||
|
||
def delete_tokens | ||
DeleteAccessToken.call(cookies[access_token_cookie_name]) | ||
DeleteRefreshToken.call(cookies[refresh_token_cookie_name]) | ||
end | ||
|
||
def delete_cookies | ||
cookies.delete(access_token_cookie_name) | ||
cookies.delete(refresh_token_cookie_name) | ||
end | ||
|
||
def access_token_cookie_name | ||
Stormpath::Rails.config.web.access_token_cookie.name | ||
end | ||
|
||
def refresh_token_cookie_name | ||
Stormpath::Rails.config.web.refresh_token_cookie.name | ||
end | ||
end | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 nice one :D but it would be good to also have remove method covered with service specs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
require 'spec_helper' | ||
|
||
describe 'IdSiteLogin GET', type: :request, vcr: true do | ||
let(:application) { Stormpath::Rails::Client.application } | ||
Timecop.freeze(Time.zone.now) do | ||
let(:time) { Time.zone.now.to_i } | ||
end | ||
let(:cb_uri) { '/id_site_result' } | ||
let(:path) { '' } | ||
let(:tenant_name) { application.tenant.name } | ||
let(:tenant_domain) { "https://#{tenant_name}.id.stormpath.io" } | ||
let(:api_key_secret) { ENV['STORMPATH_API_KEY_SECRET'] } | ||
let(:aud) { ENV['STORMPATH_API_KEY_ID'] } | ||
let(:account) { application.accounts.create(account_attrs) } | ||
let(:account_attrs) { FactoryGirl.attributes_for(:account) } | ||
let(:jwt_response) do | ||
JWT.encode( | ||
{ | ||
'iss' => tenant_domain, | ||
'sub' => account.href, | ||
'aud' => aud, | ||
'exp' => time + 1.minute.to_i, | ||
'iat' => time, | ||
'jti' => 'JX5HSMmEAevFBKJx4FfC3', | ||
'irt' => '5fbb73e7-f81b-41f2-8031-b08750da6298', | ||
'state' => '', | ||
'isNewSub' => false, | ||
'status' => 'AUTHENTICATED', | ||
'cb_uri' => 'http://localhost:3000/id_site_result' | ||
}, | ||
api_key_secret, | ||
'HS256' | ||
) | ||
end | ||
|
||
before do | ||
allow(web_config.id_site).to receive(:enabled).and_return(true) | ||
Rails.application.reload_routes! | ||
end | ||
|
||
after do | ||
account.delete if account | ||
allow(web_config.id_site).to receive(:enabled).and_return(false) | ||
Rails.application.reload_routes! | ||
end | ||
|
||
describe 'HTTP_ACCEPT=text/html' do | ||
context 'successfull login' do | ||
it 'should redirect' do | ||
get '/id_site_result', jwtResponse: jwt_response | ||
expect(response).to redirect_to('/') | ||
expect(response.status).to eq(302) | ||
end | ||
end | ||
|
||
context 'invalid jwt' do | ||
describe 'expired' do | ||
let(:time) { Time.zone.now.to_i - 10.minutes } | ||
|
||
it 'should render flash error' do | ||
get '/id_site_result', jwtResponse: jwt_response | ||
expect(controller).to set_flash[:error].now | ||
end | ||
end | ||
|
||
describe 'bad signature' do | ||
let(:api_key_secret) { 'badapikeysecret' } | ||
|
||
it 'should render flash error' do | ||
get '/id_site_result', jwtResponse: jwt_response | ||
expect(controller).to set_flash[:error].now | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe 'application/json' do | ||
let(:headers) do | ||
{ | ||
'ACCEPT' => 'application/json' | ||
} | ||
end | ||
|
||
context 'successfull login' do | ||
it 'should respond with ok' do | ||
get '/id_site_result', { jwtResponse: jwt_response }, headers | ||
expect(response.status).to eq(200) | ||
end | ||
|
||
it 'should respond with the logged in account' do | ||
get '/id_site_result', { jwtResponse: jwt_response }, headers | ||
expect(response.body).to include('account') | ||
end | ||
end | ||
|
||
context 'invalid jwt' do | ||
describe 'expired' do | ||
let(:time) { Time.zone.now.to_i - 10.minutes } | ||
|
||
it 'should raise error' do | ||
get '/id_site_result', { jwtResponse: jwt_response }, headers | ||
expect(response.body).to include('message', 'Token is invalid') | ||
end | ||
end | ||
|
||
describe 'bad signature' do | ||
let(:api_key_secret) { 'badapikeysecret' } | ||
|
||
it 'should render flash error' do | ||
get '/id_site_result', { jwtResponse: jwt_response }, headers | ||
expect(response.body).to include('message', 'Signature verification raised') | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would move to a seperate method