From 00e29758ff7a1caf31e65ab41791b7b89c4a6ffc Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 6 Sep 2021 14:04:53 +1200 Subject: [PATCH] DOC Add information regarding Security::setCurrentUser() --- .../06_Testing/01_Functional_Testing.md | 9 +++++++-- docs/en/04_Changelogs/4.9.0.md | 10 ++++++++++ src/Security/Security.php | 8 ++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/en/02_Developer_Guides/06_Testing/01_Functional_Testing.md b/docs/en/02_Developer_Guides/06_Testing/01_Functional_Testing.md index 47518edac..d1b140b82 100644 --- a/docs/en/02_Developer_Guides/06_Testing/01_Functional_Testing.md +++ b/docs/en/02_Developer_Guides/06_Testing/01_Functional_Testing.md @@ -54,11 +54,16 @@ Submits the given form (`#ContactForm`) on the current page and returns the [HTT $this->logInAs($member); ``` -Logs a given user in, sets the current session. To log all users out pass `null` to the method. +Logs a given user in, sets the current session. +When doing a functional testing it's important to use `$this->logInAs($member);` rather than simply `Security::setCurrentUser($member);` or `$this->session()->set('loggedInAs', $member->ID);` as the latter two will not run any logic contained inside login authenticators. + +## LogOut + +Log out the current user, destroys the current session. ```php -$this->logInAs(null); +$this->logOut(); ``` ## Assertions diff --git a/docs/en/04_Changelogs/4.9.0.md b/docs/en/04_Changelogs/4.9.0.md index 5914a4a23..a223e8c1e 100644 --- a/docs/en/04_Changelogs/4.9.0.md +++ b/docs/en/04_Changelogs/4.9.0.md @@ -69,6 +69,16 @@ If your site has the [symbiote/silverstripe-queuedjobs](https://github.com/symbi CMS users can review the [Session Manager user help](https://userhelp.silverstripe.org/en/4/managing_your_website/session_manager/) for more information on managing their sessions. +#### FuntionalTest's should not use `Security::setCurrentUser($member)` when mocking an HTTP request + +When writing an automated test using `FuntionalTest` the methods `$this->get()` and `$this->post()` are available to mock HTTP requests. Previously, developers could use the method `Security::setCurrentUser($member)` to define which member those mocked requests would run against. + +Because `Security::setCurrentUser()` is *stateless*, its effect only last for the current request. When mocking an HTTP request, session-manager logs out the mocked user if it was defined with `Security::setCurrentUser()`. + +Functional tests should use `$this->logInAs($member)` and `$this->logOut()` when mocking HTTP requests. It is still appropriate to use `Security::setCurrentUser()` when testing stateless logic. e.g.: Testing that a `DataObject`'s `canView()` method returns the correct value for the current user. + +Review the [Functional Testing developer documentation](/developer_guides/testing/functional_testing/#loginas) for more details on `logInAs()` and `logOut()`. + ### Default mail transport upgraded to sendmail {#sendmail} Silverstripe CMS provides an API over the top of the [SwiftMailer](http://swiftmailer.org/) PHP library which comes with an extensive list of "transports" for sending mail via different services. diff --git a/src/Security/Security.php b/src/Security/Security.php index ce5ab985e..805469c9c 100644 --- a/src/Security/Security.php +++ b/src/Security/Security.php @@ -438,6 +438,14 @@ class Security extends Controller implements TemplateGlobalProvider } /** + * The intended uses of this function is to temporarily change the current user for things such as + * canView() checks or unit tests. It is stateless and will not persist between requests. Importantly + * it also will not call any logic that may be present in the current IdentityStore logIn() or logout() methods + * + * If you are unit testing and calling FunctionalTest::get() or FunctionalTest::post() and you need to change + * the current user, you should instead use SapphireTest::logInAs() / logOut() which itself will call + * Injector::inst()->get(IdentityStore::class)->logIn($member) / logout() + * * @param null|Member $currentUser */ public static function setCurrentUser($currentUser = null)