MDL-70725 oauth2: move expectException to separate method
[moodle.git] / lib / tests / oauth2_test.php
CommitLineData
931c0234
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Tests for oauth2 apis (\core\oauth2\*).
19 *
20 * @package core
21 * @copyright 2017 Damyon Wiese
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
23 */
24
25defined('MOODLE_INTERNAL') || die();
26
27/**
1a911be5 28 * Tests for oauth2 apis (\core\oauth2\*).
931c0234
DW
29 *
30 * @package core
1a911be5 31 * @copyright 2017 Damyon Wiese
931c0234
DW
32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
33 */
34class core_oauth2_testcase extends advanced_testcase {
35
36 /**
1a911be5 37 * Tests the crud operations on oauth2 issuers.
931c0234
DW
38 */
39 public function test_create_and_delete_standard_issuers() {
40 $this->resetAfterTest();
41 $this->setAdminUser();
42 \core\oauth2\api::create_standard_issuer('google');
43 \core\oauth2\api::create_standard_issuer('facebook');
44 \core\oauth2\api::create_standard_issuer('microsoft');
3e3e120d
TR
45 \core\oauth2\api::create_standard_issuer('nextcloud', 'https://dummy.local/nextcloud/');
46
931c0234
DW
47 $issuers = \core\oauth2\api::get_all_issuers();
48
49 $this->assertEquals($issuers[0]->get('name'), 'Google');
50 $this->assertEquals($issuers[1]->get('name'), 'Facebook');
51 $this->assertEquals($issuers[2]->get('name'), 'Microsoft');
3e3e120d 52 $this->assertEquals($issuers[3]->get('name'), 'Nextcloud');
931c0234
DW
53
54 \core\oauth2\api::move_down_issuer($issuers[0]->get('id'));
55
56 $issuers = \core\oauth2\api::get_all_issuers();
57
58 $this->assertEquals($issuers[0]->get('name'), 'Facebook');
59 $this->assertEquals($issuers[1]->get('name'), 'Google');
60 $this->assertEquals($issuers[2]->get('name'), 'Microsoft');
3e3e120d 61 $this->assertEquals($issuers[3]->get('name'), 'Nextcloud');
931c0234
DW
62
63 \core\oauth2\api::delete_issuer($issuers[1]->get('id'));
64
65 $issuers = \core\oauth2\api::get_all_issuers();
66
67 $this->assertEquals($issuers[0]->get('name'), 'Facebook');
68 $this->assertEquals($issuers[1]->get('name'), 'Microsoft');
3e3e120d 69 $this->assertEquals($issuers[2]->get('name'), 'Nextcloud');
931c0234
DW
70 }
71
9975f5e2
SA
72 /**
73 * Tests the crud operations on oauth2 issuers.
74 */
75 public function test_create_nextcloud_without_url() {
76 $this->resetAfterTest();
77 $this->setAdminUser();
78
79 $this->expectException(\moodle_exception::class);
80 \core\oauth2\api::create_standard_issuer('nextcloud');
81 }
82
931c0234
DW
83 /**
84 * Tests we can list and delete each of the persistents related to an issuer.
85 */
86 public function test_getters() {
87 $this->resetAfterTest();
88 $this->setAdminUser();
89 $issuer = \core\oauth2\api::create_standard_issuer('microsoft');
90
91 $same = \core\oauth2\api::get_issuer($issuer->get('id'));
fa78244d
DW
92
93 foreach ($same->properties_definition() as $name => $def) {
94 $this->assertTrue($issuer->get($name) == $same->get($name));
95 }
931c0234
DW
96
97 $endpoints = \core\oauth2\api::get_endpoints($issuer);
98 $same = \core\oauth2\api::get_endpoint($endpoints[0]->get('id'));
99 $this->assertEquals($endpoints[0]->get('id'), $same->get('id'));
100 $this->assertEquals($endpoints[0]->get('name'), $same->get('name'));
101
102 $todelete = $endpoints[0];
103 \core\oauth2\api::delete_endpoint($todelete->get('id'));
104 $endpoints = \core\oauth2\api::get_endpoints($issuer);
105 $this->assertNotEquals($endpoints[0]->get('id'), $todelete->get('id'));
106
107 $userfields = \core\oauth2\api::get_user_field_mappings($issuer);
108 $same = \core\oauth2\api::get_user_field_mapping($userfields[0]->get('id'));
109 $this->assertEquals($userfields[0]->get('id'), $same->get('id'));
110
111 $todelete = $userfields[0];
112 \core\oauth2\api::delete_user_field_mapping($todelete->get('id'));
113 $userfields = \core\oauth2\api::get_user_field_mappings($issuer);
114 $this->assertNotEquals($userfields[0]->get('id'), $todelete->get('id'));
115 }
116
2102625e
JP
117 /**
118 * Data provider for \core_oauth2_testcase::test_get_system_oauth_client().
119 *
120 * @return array
121 */
122 public function system_oauth_client_provider() {
123 return [
124 [
125 (object) [
126 'access_token' => 'fdas...',
127 'token_type' => 'Bearer',
128 'expires_in' => '3600',
129 'id_token' => 'llfsd..',
130 ], HOURSECS - 10
131 ],
132 [
133 (object) [
134 'access_token' => 'fdas...',
135 'token_type' => 'Bearer',
136 'id_token' => 'llfsd..',
137 ], WEEKSECS
138 ],
139 ];
140 }
141
931c0234
DW
142 /**
143 * Tests we can get a logged in oauth client for a system account.
2102625e
JP
144 *
145 * @dataProvider system_oauth_client_provider
146 * @param stdClass $responsedata The response data to be mocked.
147 * @param int $expiresin The expected expiration time.
931c0234 148 */
2102625e 149 public function test_get_system_oauth_client($responsedata, $expiresin) {
931c0234
DW
150 $this->resetAfterTest();
151 $this->setAdminUser();
152
153 $issuer = \core\oauth2\api::create_standard_issuer('microsoft');
154
155 $requiredscopes = \core\oauth2\api::get_system_scopes_for_issuer($issuer);
156 // Fake a system account.
157 $data = (object) [
158 'issuerid' => $issuer->get('id'),
159 'refreshtoken' => 'abc',
dece3865
DW
160 'grantedscopes' => $requiredscopes,
161 'email' => 'sys@example.com',
162 'username' => 'sys'
931c0234
DW
163 ];
164 $sys = new \core\oauth2\system_account(0, $data);
165 $sys->create();
166
167 // Fake a response with an access token.
2102625e 168 $response = json_encode($responsedata);
931c0234
DW
169 curl::mock_response($response);
170 $client = \core\oauth2\api::get_system_oauth_client($issuer);
171 $this->assertTrue($client->is_logged_in());
2102625e
JP
172
173 // Check token expiry.
174 $accesstoken = \core\oauth2\access_token::get_record(['issuerid' => $issuer->get('id')]);
175
176 // Get the difference between the actual and expected expiry times.
177 // They might differ by a couple of seconds depending on the timing when the token gets actually processed.
178 $expiresdifference = time() + $expiresin - $accesstoken->get('expires');
179
180 // Assert that the actual token expiration is more or less the same as the expected.
181 $this->assertGreaterThanOrEqual(0, $expiresdifference);
182 $this->assertLessThanOrEqual(3, $expiresdifference);
931c0234 183 }
fa78244d
DW
184
185 /**
186 * Tests we can enable and disable an issuer.
187 */
188 public function test_enable_disable_issuer() {
fa78244d
DW
189 $this->resetAfterTest();
190 $this->setAdminUser();
191
192 $issuer = \core\oauth2\api::create_standard_issuer('microsoft');
193
194 $issuerid = $issuer->get('id');
195
196 \core\oauth2\api::enable_issuer($issuerid);
197 $check = \core\oauth2\api::get_issuer($issuer->get('id'));
198 $this->assertTrue((boolean)$check->get('enabled'));
199
200 \core\oauth2\api::enable_issuer($issuerid);
201 $check = \core\oauth2\api::get_issuer($issuer->get('id'));
202 $this->assertTrue((boolean)$check->get('enabled'));
203
204 \core\oauth2\api::disable_issuer($issuerid);
205 $check = \core\oauth2\api::get_issuer($issuer->get('id'));
206 $this->assertFalse((boolean)$check->get('enabled'));
207
208 \core\oauth2\api::enable_issuer($issuerid);
209 $check = \core\oauth2\api::get_issuer($issuer->get('id'));
210 $this->assertTrue((boolean)$check->get('enabled'));
211 }
212
213 /**
214 * Test the alloweddomains for an issuer.
215 */
216 public function test_issuer_alloweddomains() {
fa78244d
DW
217 $this->resetAfterTest();
218 $this->setAdminUser();
219
220 $issuer = \core\oauth2\api::create_standard_issuer('microsoft');
221
222 $issuer->set('alloweddomains', '');
223
224 // Anything is allowed when domain is empty.
225 $this->assertTrue($issuer->is_valid_login_domain(''));
226 $this->assertTrue($issuer->is_valid_login_domain('a@b'));
227 $this->assertTrue($issuer->is_valid_login_domain('longer.example@example.com'));
228
229 $issuer->set('alloweddomains', 'example.com');
230
231 // One domain - must match exactly - no substrings etc.
232 $this->assertFalse($issuer->is_valid_login_domain(''));
233 $this->assertFalse($issuer->is_valid_login_domain('a@b'));
234 $this->assertFalse($issuer->is_valid_login_domain('longer.example@example'));
235 $this->assertTrue($issuer->is_valid_login_domain('longer.example@example.com'));
236
237 $issuer->set('alloweddomains', 'example.com,example.net');
238 // Multiple domains - must match any exactly - no substrings etc.
239 $this->assertFalse($issuer->is_valid_login_domain(''));
240 $this->assertFalse($issuer->is_valid_login_domain('a@b'));
241 $this->assertFalse($issuer->is_valid_login_domain('longer.example@example'));
242 $this->assertFalse($issuer->is_valid_login_domain('invalid@email@example.net'));
243 $this->assertTrue($issuer->is_valid_login_domain('longer.example@example.net'));
244 $this->assertTrue($issuer->is_valid_login_domain('longer.example@example.com'));
8d90d294
DW
245
246 $issuer->set('alloweddomains', '*.example.com');
247 // Wildcard.
248 $this->assertFalse($issuer->is_valid_login_domain(''));
249 $this->assertFalse($issuer->is_valid_login_domain('a@b'));
250 $this->assertFalse($issuer->is_valid_login_domain('longer.example@example'));
251 $this->assertFalse($issuer->is_valid_login_domain('longer.example@example.com'));
252 $this->assertTrue($issuer->is_valid_login_domain('longer.example@sub.example.com'));
fa78244d
DW
253 }
254
931c0234 255}