require 'spec_helper_integration' feature 'Authorization Code Flow' do background do config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') } client_exists create_resource_owner sign_in end scenario 'resource owner authorizes the client' do visit authorization_endpoint_url(client: @client) click_on 'Authorize' access_grant_should_exist_for(@client, @resource_owner) i_should_be_on_client_callback(@client) url_should_have_param('code', Doorkeeper::AccessGrant.first.token) url_should_not_have_param('state') url_should_not_have_param('error') end scenario 'resource owner authorizes using test url' do @client.redirect_uri = Doorkeeper.configuration.native_redirect_uri @client.save! visit authorization_endpoint_url(client: @client) click_on 'Authorize' access_grant_should_exist_for(@client, @resource_owner) i_should_see 'Authorization code:' i_should_see Doorkeeper::AccessGrant.first.token end scenario 'resource owner authorizes the client with state parameter set' do visit authorization_endpoint_url(client: @client, state: 'return-me') click_on 'Authorize' url_should_have_param('code', Doorkeeper::AccessGrant.first.token) url_should_have_param('state', 'return-me') end scenario 'resource owner requests an access token with authorization code' do skip 'TODO: need to add request helpers to this feature spec' visit authorization_endpoint_url(client: @client) click_on 'Authorize' authorization_code = Doorkeeper::AccessGrant.first.token post token_endpoint_url(code: authorization_code, client: @client) access_token_should_exist_for(@client, @resource_owner) should_not_have_json 'error' should_have_json 'access_token', Doorkeeper::AccessToken.first.token should_have_json 'token_type', 'bearer' should_have_json_within 'expires_in', Doorkeeper::AccessToken.first.expires_in, 1 end context 'with scopes' do background do default_scopes_exist :public optional_scopes_exist :write end scenario 'resource owner authorizes the client with default scopes' do visit authorization_endpoint_url(client: @client) click_on 'Authorize' access_grant_should_exist_for(@client, @resource_owner) access_grant_should_have_scopes :public end scenario 'resource owner authorizes the client with required scopes' do visit authorization_endpoint_url(client: @client, scope: 'public write') click_on 'Authorize' access_grant_should_have_scopes :public, :write end scenario 'resource owner authorizes the client with required scopes (without defaults)' do visit authorization_endpoint_url(client: @client, scope: 'write') click_on 'Authorize' access_grant_should_have_scopes :write end scenario 'new access token matches required scopes' do skip 'TODO: need to add request helpers to this feature spec' visit authorization_endpoint_url(client: @client, scope: 'public write') click_on 'Authorize' authorization_code = Doorkeeper::AccessGrant.first.token post token_endpoint_url(code: authorization_code, client: @client) access_token_should_exist_for(@client, @resource_owner) access_token_should_have_scopes :public, :write end scenario 'returns new token if scopes have changed' do skip 'TODO: need to add request helpers to this feature spec' client_is_authorized(@client, @resource_owner, scopes: 'public write') visit authorization_endpoint_url(client: @client, scope: 'public') click_on 'Authorize' authorization_code = Doorkeeper::AccessGrant.first.token post token_endpoint_url(code: authorization_code, client: @client) expect(Doorkeeper::AccessToken.count).to be(2) should_have_json 'access_token', Doorkeeper::AccessToken.last.token end scenario 'resource owner authorizes the client with extra scopes' do skip 'TODO: need to add request helpers to this feature spec' client_is_authorized(@client, @resource_owner, scopes: 'public') visit authorization_endpoint_url(client: @client, scope: 'public write') click_on 'Authorize' authorization_code = Doorkeeper::AccessGrant.first.token post token_endpoint_url(code: authorization_code, client: @client) expect(Doorkeeper::AccessToken.count).to be(2) should_have_json 'access_token', Doorkeeper::AccessToken.last.token access_token_should_have_scopes :public, :write end end end describe 'Authorization Code Flow' do before do Doorkeeper.configure do orm DOORKEEPER_ORM use_refresh_token end client_exists end context 'issuing a refresh token' do before do authorization_code_exists application: @client end it 'second of simultaneous client requests get an error for revoked acccess token' do authorization_code = Doorkeeper::AccessGrant.first.token allow_any_instance_of(Doorkeeper::AccessGrant).to receive(:revoked?).and_return(false, true) post token_endpoint_url(code: authorization_code, client: @client) should_not_have_json 'access_token' should_have_json 'error', 'invalid_grant' end end end