require 'spec_helper' describe 'Resource Owner Password Credentials Flow not set up' do before do client_exists create_resource_owner end context 'with valid user credentials' do it 'does not issue new token' do expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to_not(change { Doorkeeper::AccessToken.count }) end end end describe 'Resource Owner Password Credentials Flow' do let(:client_attributes) { {} } before do config_is_set(:grant_flows, ["password"]) config_is_set(:resource_owner_from_credentials) { User.authenticate! params[:username], params[:password] } client_exists(client_attributes) create_resource_owner end context 'with valid user credentials' do context "with non-confidential/public client" do let(:client_attributes) { { confidential: false } } context "when client_secret absent" do it "should issue new token" do expect do post password_token_endpoint_url(client_id: @client.uid, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token end end context "when client_secret present" do it "should issue new token" do expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token end context "when client_secret incorrect" do it "should not issue new token" do expect do post password_token_endpoint_url(client_id: @client.uid, client_secret: 'foobar', resource_owner: @resource_owner) end.not_to(change { Doorkeeper::AccessToken.count }) expect(response).not_to be_ok end end end end context "with confidential/private client" do it "should issue new token" do expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token end context "when client_secret absent" do it "should not issue new token" do expect do post password_token_endpoint_url(client_id: @client.uid, resource_owner: @resource_owner) end.not_to(change { Doorkeeper::AccessToken.count }) expect(response).not_to be_ok end end end it 'should issue new token without client credentials' do expect do post password_token_endpoint_url(resource_owner: @resource_owner) end.to(change { Doorkeeper::AccessToken.count }.by(1)) token = Doorkeeper::AccessToken.first expect(token.application_id).to be_nil should_have_json 'access_token', token.token end it 'should issue a refresh token if enabled' do config_is_set(:refresh_token_enabled, true) post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) token = Doorkeeper::AccessToken.first should_have_json 'refresh_token', token.refresh_token end it 'should return the same token if it is still accessible' do allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true) client_is_authorized(@client, @resource_owner) post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) expect(Doorkeeper::AccessToken.count).to be(1) should_have_json 'access_token', Doorkeeper::AccessToken.first.token end context 'with valid, default scope' do before do default_scopes_exist :public end it 'should issue new token' do expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner, scope: 'public') end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token should_have_json 'scope', 'public' end end end context 'when application scopes are present and differs from configured default scopes and no scope is passed' do before do default_scopes_exist :public @client.update_attributes(scopes: 'abc') end it 'issues new token without any scope' do expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id expect(token.scopes).to be_empty should_have_json 'access_token', token.token should_not_have_json 'scope' end end context 'when application scopes contain some of the default scopes and no scope is passed' do before do @client.update_attributes(scopes: 'read write public') end it 'issues new token with one default scope that are present in application scopes' do default_scopes_exist :public, :admin expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token should_have_json 'scope', 'public' end it 'issues new token with multiple default scopes that are present in application scopes' do default_scopes_exist :public, :read, :update expect do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner) end.to change { Doorkeeper::AccessToken.count }.by(1) token = Doorkeeper::AccessToken.first expect(token.application_id).to eq @client.id should_have_json 'access_token', token.token should_have_json 'scope', 'public read' end end context 'with invalid scopes' do subject do post password_token_endpoint_url(client: @client, resource_owner: @resource_owner, scope: 'random') end it 'should not issue new token' do expect { subject }.to_not(change { Doorkeeper::AccessToken.count }) end it 'should return invalid_scope error' do subject should_have_json 'error', 'invalid_scope' should_have_json 'error_description', translated_error_message(:invalid_scope) should_not_have_json 'access_token' expect(response.status).to eq(401) end end context 'with invalid user credentials' do it 'should not issue new token with bad password' do expect do post password_token_endpoint_url(client: @client, resource_owner_username: @resource_owner.name, resource_owner_password: 'wrongpassword') end.to_not(change { Doorkeeper::AccessToken.count }) end it 'should not issue new token without credentials' do expect do post password_token_endpoint_url(client: @client) end.to_not(change { Doorkeeper::AccessToken.count }) end end context 'with invalid confidential client credentials' do it 'should not issue new token with bad client credentials' do expect do post password_token_endpoint_url(client_id: @client.uid, client_secret: 'bad_secret', resource_owner: @resource_owner) end.to_not(change { Doorkeeper::AccessToken.count }) end end context 'with invalid public client id' do it 'should not issue new token with bad client id' do expect do post password_token_endpoint_url(client_id: 'bad_id', resource_owner: @resource_owner) end.to_not(change { Doorkeeper::AccessToken.count }) end end end