diff --git a/app/controllers/api/openid_connect/authorizations_controller.rb b/app/controllers/api/openid_connect/authorizations_controller.rb index 148441fb9..e31d001bd 100644 --- a/app/controllers/api/openid_connect/authorizations_controller.rb +++ b/app/controllers/api/openid_connect/authorizations_controller.rb @@ -10,7 +10,9 @@ module Api def new auth = Api::OpenidConnect::Authorization.find_by_client_id_and_user(params[:client_id], current_user) - if params[:prompt] + if logged_in_before?(params[:max_age]) + reauthenticate + elsif params[:prompt] prompt = params[:prompt].split(" ") handle_prompt(prompt, auth) else @@ -41,9 +43,8 @@ module Api "There is no support for choosing among multiple accounts") elsif prompt.include? "none" handle_prompt_none(prompt, auth) - elsif prompt.include?("login") && logged_in_more_than_5_minutes_ago? - handle_prompt_params_error("login_required", - "There is no support for re-authenticating already authenticated users") + elsif prompt.include?("login") && logged_in_before?(60) + reauthenticate elsif prompt.include? "consent" request_authorization_consent_form else @@ -51,6 +52,13 @@ module Api end end + def reauthenticate + sign_out current_user + params_as_get_query = params.map {|key, value| key.to_s + "=" + value }.join("&") + authorization_path_with_query = new_api_openid_connect_authorization_path + "?" + params_as_get_query + redirect_to authorization_path_with_query + end + def handle_authorization_form(auth) if auth process_authorization_consent("true") @@ -64,8 +72,12 @@ module Api handle_start_point_response(endpoint) end - def logged_in_more_than_5_minutes_ago? - (current_user.current_sign_in_at.to_i - Time.zone.now.to_i) > 300 + def logged_in_before?(seconds) + if seconds.nil? + false + else + (Time.zone.now.utc.to_i - current_user.current_sign_in_at.to_i) > seconds.to_i + end end def handle_prompt_none(prompt, auth) diff --git a/features/desktop/oidc_implicit_flow.feature b/features/desktop/oidc_implicit_flow.feature index 480b0a928..8ded34fd3 100644 --- a/features/desktop/oidc_implicit_flow.feature +++ b/features/desktop/oidc_implicit_flow.feature @@ -6,20 +6,30 @@ Feature: Access protected resources using implicit flow 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 send a post request from that client to the 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 send a post request from that client to the 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 send a post request from that client to the 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 + + Scenario: Application is authorized and uses small value for the max_age parameter + When I register a new client + And I sign in as "kent@kent.kent" + And I pass time + And I send a post request from that client to the authorization endpoint with max age 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 diff --git a/features/step_definitions/implicit_flow_steps.rb b/features/step_definitions/implicit_flow_steps.rb index 844cf3f96..5e07969bf 100644 --- a/features/step_definitions/implicit_flow_steps.rb +++ b/features/step_definitions/implicit_flow_steps.rb @@ -7,13 +7,33 @@ o_auth_query_params = %i( prompt=login ).join("&") -Given /^I send a post request from that client to the implicit flow authorization endpoint$/ do +o_auth_query_params_with_max_age = %i( + redirect_uri=http://localhost:3000 + response_type=id_token%20token + scope=openid%20read + nonce=hello + state=hi + prompt=login + max_age=30 +).join("&") + +Given /^I send a post request from that client to the authorization endpoint$/ do client_json = JSON.parse(last_response.body) visit new_api_openid_connect_authorization_path + "?client_id=#{client_json['client_id']}&#{o_auth_query_params}" end -Given /^I send a post request from that client to the implicit flow authorization endpoint using a invalid client id/ do +Given /^I pass time$/ do + Timecop.travel(Time.zone.now + 1.minute) +end + +Given /^I send a post request from that client to the authorization endpoint with max age$/ do + client_json = JSON.parse(last_response.body) + visit new_api_openid_connect_authorization_path + + "?client_id=#{client_json['client_id']}&#{o_auth_query_params_with_max_age}" +end + +Given /^I send a post request from that client to the authorization endpoint using a invalid client id$/ do visit new_api_openid_connect_authorization_path + "?client_id=randomid&#{o_auth_query_params}" end diff --git a/features/step_definitions/password_flow_steps.rb b/features/step_definitions/password_flow_steps.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/controllers/api/openid_connect/authorizations_controller_spec.rb b/spec/controllers/api/openid_connect/authorizations_controller_spec.rb index 4e616388a..244799a28 100644 --- a/spec/controllers/api/openid_connect/authorizations_controller_spec.rb +++ b/spec/controllers/api/openid_connect/authorizations_controller_spec.rb @@ -301,7 +301,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do context "with non-existent authorization" do it "raises an error" do - expect{ delete :destroy, id: 123456789 }.to raise_error(ArgumentError) + expect { delete :destroy, id: 123_456_789 }.to raise_error(ArgumentError) end end end