|
1 |
# frozen_string_literal: true
|
|
2 |
|
|
3 |
require File.expand_path('../../application_system_test_case', __FILE__)
|
|
4 |
require 'oauth2'
|
|
5 |
|
|
6 |
class OauthProviderSystemTest < ApplicationSystemTestCase
|
|
7 |
|
|
8 |
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
|
9 |
:trackers, :projects_trackers, :enabled_modules, :issue_statuses, :issues,
|
|
10 |
:enumerations, :custom_fields, :custom_values, :custom_fields_trackers,
|
|
11 |
:watchers, :journals, :journal_details, :versions,
|
|
12 |
:workflows
|
|
13 |
|
|
14 |
|
|
15 |
test 'application creation and authorization' do
|
|
16 |
# admin creates the application, granting permissions and generating a uuid
|
|
17 |
# and secret.
|
|
18 |
log_user 'admin', 'admin'
|
|
19 |
with_settings rest_api_enabled: 1 do
|
|
20 |
visit '/admin'
|
|
21 |
within 'div#admin-menu ul' do
|
|
22 |
click_link 'Applications'
|
|
23 |
end
|
|
24 |
click_link 'New Application'
|
|
25 |
fill_in 'Name', with: 'Oauth Test'
|
|
26 |
fill_in 'Redirect URI', with: 'urn:ietf:wg:oauth:2.0:oob'
|
|
27 |
find('#doorkeeper_application_scopes_view_issues').set(true)
|
|
28 |
click_button 'Create'
|
|
29 |
end
|
|
30 |
|
|
31 |
assert app = Doorkeeper::Application.find_by_name('Oauth Test')
|
|
32 |
|
|
33 |
find 'h2', visible: true, text: /Oauth Test/
|
|
34 |
find 'p code', visible: true, text: app.uid
|
|
35 |
find 'p code', visible: true, text: app.secret
|
|
36 |
find 'p code', visible: true, text: /View Issues/
|
|
37 |
click_link 'Sign out'
|
|
38 |
|
|
39 |
# regular user authorizes the application to act on his behalf
|
|
40 |
|
|
41 |
client = OAuth2::Client.new(app.uid, app.secret, site: "http://localhost:#{test_port}/")
|
|
42 |
|
|
43 |
log_user 'jsmith', 'jsmith'
|
|
44 |
with_settings rest_api_enabled: 1 do
|
|
45 |
visit '/my/account'
|
|
46 |
click_link 'Your applications'
|
|
47 |
find 'p.nodata', visible: true
|
|
48 |
|
|
49 |
# an oauth client would send the user to this url for him to grant
|
|
50 |
# permission:
|
|
51 |
url = client.auth_code.authorize_url redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', scope: 'view_issues view_project'
|
|
52 |
uri = URI.parse url
|
|
53 |
visit uri.path+'?'+uri.query
|
|
54 |
|
|
55 |
find 'h2', visible: true, text: 'Authorization required'
|
|
56 |
find 'p', visible: true, text: /Authorize Oauth Test/
|
|
57 |
find '.oauth-permissions', visible: true, text: /View Issues/
|
|
58 |
find '.oauth-permissions', visible: true, text: /View project/
|
|
59 |
|
|
60 |
click_button 'Authorize'
|
|
61 |
assert grant = app.access_grants.last
|
|
62 |
assert_equal 'view_issues view_project', grant.scopes.to_s
|
|
63 |
|
|
64 |
find 'p', visible: true, text: /Authorization code/
|
|
65 |
find 'p', visible: true, text: grant.token
|
|
66 |
|
|
67 |
# exchange the code for an access token
|
|
68 |
token = client.auth_code.get_token(grant.token, redirect_uri: 'urn:ietf:wg:oauth:2.0:oob')
|
|
69 |
|
|
70 |
visit '/my/account'
|
|
71 |
click_link 'Your applications'
|
|
72 |
find 'td', visible: true, text: /Oauth Test/
|
|
73 |
click_link 'Sign out'
|
|
74 |
|
|
75 |
# Now, use the token for some API requests
|
|
76 |
assert_raise(RestClient::Unauthorized) do
|
|
77 |
RestClient.get "http://localhost:#{test_port}/projects/onlinestore/issues.json"
|
|
78 |
end
|
|
79 |
|
|
80 |
headers = { 'Authorization' => "Bearer #{token.token}" }
|
|
81 |
r = RestClient.get "http://localhost:#{test_port}/projects/onlinestore/issues.json", headers
|
|
82 |
issues = JSON.parse(r.body)['issues']
|
|
83 |
assert issues.any?
|
|
84 |
|
|
85 |
# time entries access is not part of the granted scopes
|
|
86 |
assert_raise(RestClient::Forbidden) do
|
|
87 |
RestClient.get "http://localhost:#{test_port}/projects/onlinestore/time_entries.json", headers
|
|
88 |
end
|
|
89 |
end
|
|
90 |
end
|
|
91 |
|
|
92 |
private
|
|
93 |
|
|
94 |
def test_port
|
|
95 |
Capybara.current_session.server.port
|
|
96 |
end
|
|
97 |
end
|
|
98 |
|