]> BookStack Code Mirror - bookstack/blob - tests/Auth/AuthTest.php
Merge branch 'v0.24-dev'
[bookstack] / tests / Auth / AuthTest.php
1 <?php namespace Tests;
2
3 use BookStack\Notifications\ConfirmEmail;
4 use BookStack\Auth\User;
5 use BookStack\Settings\SettingService;
6 use Illuminate\Support\Facades\Notification;
7
8 class AuthTest extends BrowserKitTest
9 {
10
11     public function test_auth_working()
12     {
13         $this->visit('/')
14             ->seePageIs('/login');
15     }
16
17     public function test_login()
18     {
19         $this->login('[email protected]', 'password')
20             ->seePageIs('/');
21     }
22
23     public function test_public_viewing()
24     {
25         $settings = app(SettingService::class);
26         $settings->put('app-public', 'true');
27         $this->visit('/')
28             ->seePageIs('/')
29             ->see('Log In');
30     }
31
32     public function test_registration_showing()
33     {
34         // Ensure registration form is showing
35         $this->setSettings(['registration-enabled' => 'true']);
36         $this->visit('/login')
37             ->see('Sign up')
38             ->click('Sign up')
39             ->seePageIs('/register');
40     }
41
42     public function test_normal_registration()
43     {
44         // Set settings and get user instance
45         $this->setSettings(['registration-enabled' => 'true']);
46         $user = factory(User::class)->make();
47
48         // Test form and ensure user is created
49         $this->visit('/register')
50             ->see('Sign Up')
51             ->type($user->name, '#name')
52             ->type($user->email, '#email')
53             ->type($user->password, '#password')
54             ->press('Create Account')
55             ->seePageIs('/')
56             ->see($user->name)
57             ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email]);
58     }
59
60     public function test_empty_registration_redirects_back_with_errors()
61     {
62         // Set settings and get user instance
63         $this->setSettings(['registration-enabled' => 'true']);
64
65         // Test form and ensure user is created
66         $this->visit('/register')
67             ->press('Create Account')
68             ->see('The name field is required')
69             ->seePageIs('/register');
70     }
71
72
73     public function test_confirmed_registration()
74     {
75         // Fake notifications
76         Notification::fake();
77
78         // Set settings and get user instance
79         $this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'true']);
80         $user = factory(User::class)->make();
81
82         // Go through registration process
83         $this->visit('/register')
84             ->see('Sign Up')
85             ->type($user->name, '#name')
86             ->type($user->email, '#email')
87             ->type($user->password, '#password')
88             ->press('Create Account')
89             ->seePageIs('/register/confirm')
90             ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => false]);
91
92         // Ensure notification sent
93         $dbUser = User::where('email', '=', $user->email)->first();
94         Notification::assertSentTo($dbUser, ConfirmEmail::class);
95
96         // Test access and resend confirmation email
97         $this->login($user->email, $user->password)
98             ->seePageIs('/register/confirm/awaiting')
99             ->see('Resend')
100             ->visit('/books')
101             ->seePageIs('/register/confirm/awaiting')
102             ->press('Resend Confirmation Email');
103
104         // Get confirmation and confirm notification matches
105         $emailConfirmation = \DB::table('email_confirmations')->where('user_id', '=', $dbUser->id)->first();
106         Notification::assertSentTo($dbUser, ConfirmEmail::class, function($notification, $channels) use ($emailConfirmation) {
107             return $notification->token === $emailConfirmation->token;
108         });
109         
110         // Check confirmation email confirmation activation.
111         $this->visit('/register/confirm/' . $emailConfirmation->token)
112             ->seePageIs('/')
113             ->see($user->name)
114             ->notSeeInDatabase('email_confirmations', ['token' => $emailConfirmation->token])
115             ->seeInDatabase('users', ['name' => $dbUser->name, 'email' => $dbUser->email, 'email_confirmed' => true]);
116     }
117
118     public function test_restricted_registration()
119     {
120         $this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'true', 'registration-restrict' => 'example.com']);
121         $user = factory(User::class)->make();
122         // Go through registration process
123         $this->visit('/register')
124             ->type($user->name, '#name')
125             ->type($user->email, '#email')
126             ->type($user->password, '#password')
127             ->press('Create Account')
128             ->seePageIs('/register')
129             ->dontSeeInDatabase('users', ['email' => $user->email])
130             ->see('That email domain does not have access to this application');
131
132         $user->email = '[email protected]';
133
134         $this->visit('/register')
135             ->type($user->name, '#name')
136             ->type($user->email, '#email')
137             ->type($user->password, '#password')
138             ->press('Create Account')
139             ->seePageIs('/register/confirm')
140             ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => false]);
141
142         $this->visit('/')->seePageIs('/login')
143             ->type($user->email, '#email')
144             ->type($user->password, '#password')
145             ->press('Log In')
146             ->seePageIs('/register/confirm/awaiting')
147             ->seeText('Email Address Not Confirmed');
148     }
149
150     public function test_restricted_registration_with_confirmation_disabled()
151     {
152         $this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'false', 'registration-restrict' => 'example.com']);
153         $user = factory(User::class)->make();
154         // Go through registration process
155         $this->visit('/register')
156             ->type($user->name, '#name')
157             ->type($user->email, '#email')
158             ->type($user->password, '#password')
159             ->press('Create Account')
160             ->seePageIs('/register')
161             ->dontSeeInDatabase('users', ['email' => $user->email])
162             ->see('That email domain does not have access to this application');
163
164         $user->email = '[email protected]';
165
166         $this->visit('/register')
167             ->type($user->name, '#name')
168             ->type($user->email, '#email')
169             ->type($user->password, '#password')
170             ->press('Create Account')
171             ->seePageIs('/register/confirm')
172             ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => false]);
173
174         $this->visit('/')->seePageIs('/login')
175             ->type($user->email, '#email')
176             ->type($user->password, '#password')
177             ->press('Log In')
178             ->seePageIs('/register/confirm/awaiting')
179             ->seeText('Email Address Not Confirmed');
180     }
181
182     public function test_user_creation()
183     {
184         $user = factory(User::class)->make();
185
186         $this->asAdmin()
187             ->visit('/settings/users')
188             ->click('Add New User')
189             ->type($user->name, '#name')
190             ->type($user->email, '#email')
191             ->check('roles[admin]')
192             ->type($user->password, '#password')
193             ->type($user->password, '#password-confirm')
194             ->press('Save')
195             ->seePageIs('/settings/users')
196             ->seeInDatabase('users', $user->toArray())
197             ->see($user->name);
198     }
199
200     public function test_user_updating()
201     {
202         $user = $this->getNormalUser();
203         $password = $user->password;
204         $this->asAdmin()
205             ->visit('/settings/users')
206             ->click($user->name)
207             ->seePageIs('/settings/users/' . $user->id)
208             ->see($user->email)
209             ->type('Barry Scott', '#name')
210             ->press('Save')
211             ->seePageIs('/settings/users')
212             ->seeInDatabase('users', ['id' => $user->id, 'name' => 'Barry Scott', 'password' => $password])
213             ->notSeeInDatabase('users', ['name' => $user->name]);
214     }
215
216     public function test_user_password_update()
217     {
218         $user = $this->getNormalUser();
219         $userProfilePage = '/settings/users/' . $user->id;
220         $this->asAdmin()
221             ->visit($userProfilePage)
222             ->type('newpassword', '#password')
223             ->press('Save')
224             ->seePageIs($userProfilePage)
225             ->see('Password confirmation required')
226
227             ->type('newpassword', '#password')
228             ->type('newpassword', '#password-confirm')
229             ->press('Save')
230             ->seePageIs('/settings/users');
231
232             $userPassword = User::find($user->id)->password;
233             $this->assertTrue(\Hash::check('newpassword', $userPassword));
234     }
235
236     public function test_user_deletion()
237     {
238         $userDetails = factory(User::class)->make();
239         $user = $this->getEditor($userDetails->toArray());
240
241         $this->asAdmin()
242             ->visit('/settings/users/' . $user->id)
243             ->click('Delete User')
244             ->see($user->name)
245             ->press('Confirm')
246             ->seePageIs('/settings/users')
247             ->notSeeInDatabase('users', ['name' => $user->name]);
248     }
249
250     public function test_user_cannot_be_deleted_if_last_admin()
251     {
252         $adminRole = \BookStack\Auth\Role::getRole('admin');
253         // Ensure we currently only have 1 admin user
254         $this->assertEquals(1, $adminRole->users()->count());
255         $user = $adminRole->users->first();
256
257         $this->asAdmin()->visit('/settings/users/' . $user->id)
258             ->click('Delete User')
259             ->press('Confirm')
260             ->seePageIs('/settings/users/' . $user->id)
261             ->see('You cannot delete the only admin');
262     }
263
264     public function test_logout()
265     {
266         $this->asAdmin()
267             ->visit('/')
268             ->seePageIs('/')
269             ->visit('/logout')
270             ->visit('/')
271             ->seePageIs('/login');
272     }
273
274     public function test_reset_password_flow()
275     {
276
277         Notification::fake();
278
279         $this->visit('/login')->click('Forgot Password?')
280             ->seePageIs('/password/email')
281             ->type('[email protected]', 'email')
282             ->press('Send Reset Link')
283             ->see('A password reset link has been sent to [email protected]');
284
285         $this->seeInDatabase('password_resets', [
286             'email' => '[email protected]'
287         ]);
288
289         $user = User::where('email', '=', '[email protected]')->first();
290
291         Notification::assertSentTo($user, \BookStack\Notifications\ResetPassword::class);
292         $n = Notification::sent($user, \BookStack\Notifications\ResetPassword::class);
293
294         $this->visit('/password/reset/' . $n->first()->token)
295             ->see('Reset Password')
296             ->submitForm('Reset Password', [
297                 'email' => '[email protected]',
298                 'password' => 'randompass',
299                 'password_confirmation' => 'randompass'
300             ])->seePageIs('/')
301             ->see('Your password has been successfully reset');
302     }
303
304     public function test_reset_password_page_shows_sign_links()
305     {
306         $this->setSettings(['registration-enabled' => 'true']);
307         $this->visit('/password/email')
308             ->seeLink('Log in')
309             ->seeLink('Sign up');
310     }
311
312     /**
313      * Perform a login
314      * @param string $email
315      * @param string $password
316      * @return $this
317      */
318     protected function login($email, $password)
319     {
320         return $this->visit('/login')
321             ->type($email, '#email')
322             ->type($password, '#password')
323             ->press('Log In');
324     }
325 }