From 2be932ceffaa4bac23668630706631f16858b01f Mon Sep 17 00:00:00 2001 From: theworldbright Date: Fri, 31 Jul 2015 01:46:14 +0900 Subject: [PATCH] Delete password flow --- features/desktop/oauth_password_flow.feature | 21 ------ .../step_definitions/oidc_common_steps.rb | 30 ++++++++ .../step_definitions/password_flow_steps.rb | 48 ------------ lib/api/openid_connect/token_endpoint.rb | 16 ---- .../api/openid_connect/token_endpoint_spec.rb | 73 ------------------- 5 files changed, 30 insertions(+), 158 deletions(-) delete mode 100644 features/desktop/oauth_password_flow.feature create mode 100644 features/step_definitions/oidc_common_steps.rb diff --git a/features/desktop/oauth_password_flow.feature b/features/desktop/oauth_password_flow.feature deleted file mode 100644 index 4bde1b08d..000000000 --- a/features/desktop/oauth_password_flow.feature +++ /dev/null @@ -1,21 +0,0 @@ -Feature: Access protected resources using password flow - Background: - Given a user with username "kent" - And all scopes exist - - Scenario: Invalid credentials to token endpoint - When I register a new client - 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 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 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 diff --git a/features/step_definitions/oidc_common_steps.rb b/features/step_definitions/oidc_common_steps.rb new file mode 100644 index 000000000..1519e26fc --- /dev/null +++ b/features/step_definitions/oidc_common_steps.rb @@ -0,0 +1,30 @@ +Given(/^all scopes exist$/) do + Api::OpenidConnect::Scope.find_or_create_by(name: "openid") + Api::OpenidConnect::Scope.find_or_create_by(name: "read") +end + +When /^I register a new client$/ do + post api_openid_connect_clients_path, redirect_uris: ["http://localhost:3000"], client_name: "diaspora client" +end + +When /^I use received valid bearer tokens to access user info$/ do + access_token_json = JSON.parse(last_response.body) + get api_v0_user_path, access_token: access_token_json["access_token"] +end + +When /^I use invalid bearer tokens to access user info$/ do + get api_v0_user_path, access_token: SecureRandom.hex(32) +end + +Then /^I should receive "([^\"]*)"'s id, username, and email$/ do |username| + user_info_json = JSON.parse(last_response.body) + user = User.find_by_username(username) + expect(user_info_json["username"]).to have_content(user.username) + expect(user_info_json["language"]).to have_content(user.language) + expect(user_info_json["email"]).to have_content(user.email) +end + +Then /^I should receive an "([^\"]*)" error$/ do |error_message| + user_info_json = JSON.parse(last_response.body) + expect(user_info_json["error"]).to have_content(error_message) +end diff --git a/features/step_definitions/password_flow_steps.rb b/features/step_definitions/password_flow_steps.rb index 2a68d1082..e69de29bb 100644 --- a/features/step_definitions/password_flow_steps.rb +++ b/features/step_definitions/password_flow_steps.rb @@ -1,48 +0,0 @@ -Given(/^all scopes exist$/) do - Api::OpenidConnect::Scope.find_or_create_by(name: "openid") - Api::OpenidConnect::Scope.find_or_create_by(name: "read") -end - -When /^I register a new client$/ do - post api_openid_connect_clients_path, redirect_uris: ["http://localhost:3000"], client_name: "diaspora client" -end - -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) - post api_openid_connect_access_tokens_path, grant_type: "password", username: user.username, - password: "password", # Password has been hard coded as all test accounts seem to have a password of "password" - client_id: client_json["o_auth_application"]["client_id"], - client_secret: client_json["o_auth_application"]["client_secret"], - scope: "read" -end - -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) - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", password: "wrongpassword", - client_id: client_json["o_auth_application"]["client_id"], - client_secret: client_json["o_auth_application"]["client_secret"], - scope: "read" -end - -When /^I use received valid bearer tokens to access user info$/ do - access_token_json = JSON.parse(last_response.body) - get api_v0_user_path, access_token: access_token_json["access_token"] -end - -When /^I use invalid bearer tokens to access user info$/ do - get api_v0_user_path, access_token: SecureRandom.hex(32) -end - -Then /^I should receive "([^\"]*)"'s id, username, and email$/ do |username| - user_info_json = JSON.parse(last_response.body) - user = User.find_by_username(username) - expect(user_info_json["username"]).to have_content(user.username) - expect(user_info_json["language"]).to have_content(user.language) - expect(user_info_json["email"]).to have_content(user.email) -end - -Then /^I should receive an "([^\"]*)" error$/ do |error_message| - user_info_json = JSON.parse(last_response.body) - expect(user_info_json["error"]).to have_content(error_message) -end diff --git a/lib/api/openid_connect/token_endpoint.rb b/lib/api/openid_connect/token_endpoint.rb index 7ae0e7dbd..1f592c03c 100644 --- a/lib/api/openid_connect/token_endpoint.rb +++ b/lib/api/openid_connect/token_endpoint.rb @@ -17,8 +17,6 @@ module Api def handle_flows(o_auth_app, req, res) case req.grant_type - when :password - handle_password_flow(o_auth_app, req, res) when :refresh_token handle_refresh_flow(req, res) when :authorization_code @@ -34,20 +32,6 @@ module Api end end - 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_by(o_auth_application: o_auth_app, user: user) - build_auth_and_access_token(auth, req, res) - else - req.invalid_grant! - end - else - req.invalid_grant! # TODO: Change to user login: Perhaps redirect_to login_path? - end - end - def build_auth_and_access_token(auth, req, res) scope_list = req.scope.map { |scope_name| OpenidConnect::Scope.find_by(name: scope_name).tap do |scope| diff --git a/spec/lib/api/openid_connect/token_endpoint_spec.rb b/spec/lib/api/openid_connect/token_endpoint_spec.rb index 85219cb00..69228bcaf 100644 --- a/spec/lib/api/openid_connect/token_endpoint_spec.rb +++ b/spec/lib/api/openid_connect/token_endpoint_spec.rb @@ -75,79 +75,6 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do end end - describe "the password grant type" do - context "when the username field is missing" do - it "should return an invalid request error" do - post api_openid_connect_access_tokens_path, grant_type: "password", password: "bluepin7", - client_id: client.client_id, client_secret: client.client_secret, scope: "read" - expect(response.body).to include "'username' required" - end - end - - context "when the password field is missing" do - it "should return an invalid request error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", - client_id: client.client_id, client_secret: client.client_secret, scope: "read" - expect(response.body).to include "'password' required" - end - end - - context "when the username does not match an existing user" do - it "should return an invalid request error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "randomnoexist", - password: "bluepin7", client_id: client.client_id, client_secret: client.client_secret, scope: "read" - expect(response.body).to include "invalid_grant" - end - end - - context "when the password is invalid" do - it "should return an invalid request error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", - password: "wrongpassword", client_id: client.client_id, client_secret: client.client_secret, scope: "read" - expect(response.body).to include "invalid_grant" - end - end - - context "when the client_secret doesn't match" do - it "should return an invalid client error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", - password: "bluepin7", client_id: client.client_id, client_secret: "client.client_secret", scope: "read" - expect(response.body).to include "invalid_client" - end - end - - context "when the request is valid" do - it "should return an access token" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", - password: "bluepin7", client_id: client.client_id, client_secret: client.client_secret, scope: "read" - json = JSON.parse(response.body) - expect(json.keys).to include "expires_in" - expect(json["access_token"].length).to eq(64) - expect(json["token_type"]).to eq("bearer") - end - end - - context "when there are duplicate fields" do - it "should return an invalid request error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", password: "bluepin7", - username: "bob", password: "bluepin6", client_id: client.client_id, client_secret: client.client_secret, - scope: "read" - expect(response.body).to include "invalid_grant" - end - end - - context "when the client is unregistered" do - it "should return an error" do - post api_openid_connect_access_tokens_path, grant_type: "password", username: "bob", - password: "bluepin7", client_id: SecureRandom.hex(16).to_s, client_secret: client.client_secret, - scope: "read" - expect(response.body).to include "invalid_client" - end - end - # TODO: Support a way to prevent brute force attacks using rate-limitation - # as specified by RFC 6749 4.3.2 Access Token Request - end - describe "an unsupported grant type" do it "should return an unsupported grant type error" do post api_openid_connect_access_tokens_path, grant_type: "noexistgrant", username: "bob",