laravel dusk test login to wordpress unable to set cookie - wordpress

I am using laravel dusk to login to a wordpress site using the function below
public function testLoginPage()
{
$this->browse(function (Browser $browser) {
$browser->visit('http://localhost/wordpress/wp-login.php')
->waitFor('#wp-submit')
->value('#user_login', '***')
->value('#user_pass', '***')
->click('#wp-submit')
->waitFor('#footer-thankyou')
->assertSee('Thank you for creating with');
$this->saveCookies($browser);
});
}
and saving the cookie created
protected $cookie_file = 'cookies.txt';
private function saveCookies(Browser $browser) {
$cookies = $browser->driver->manage()->getCookies();
file_put_contents($this->cookie_file, serialize($cookies));
}
private function loadCookies(Browser $browser) {
if (file_exists($this->cookie_file)) {
//Get cookies from storage
$cookies = unserialize(file_get_contents($this->cookie_file));
//Add each cookie to this session
foreach ($cookies as $key => $cookie) {
$browser->driver->manage()->addCookie($cookie);
}
}
}
Now I login successfully and the cookie also gets created
But when I try A page in the admin like the update page I get the error that unable to set cookie (Session info: chrome=86.0.4240.75)
public function testUpdateAllPlugins()
{
$this->browse(function (Browser $browser) {
$this->loadCookies($browser);
$browser->visit('http://localhost/wp-admin/update-core.php')
->waitFor('#plugins-select-all')
->check('#plugins-select-all')
->click('#upgrade-plugins')
#->withinFrame('iframe[title="Update progress"]', function($browser){
->withinFrame('.wrap > iframe', function($browser){
$browser
->assertSee('All updates have been completed');
});
});
}
I need to be able to visit all the admin pages after the login so My question is How Do I set and use the cookie from the laravel dusk to wordpress site.
I am using the below namespace in the testcase
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Facebook\WebDriver\Cookie;
use Facebook\WebDriver\WebDriverOptions;
use Laravel\Dusk\Chrome\ChromeProcess;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;

I got it working using the code for the visit right after the login one instead of setting a cookie and using a different method to visit the browser.

Related

SilverStripe 4 : FunctionalTest "get" method returns 404 status although the page is there.

I am trying to test a controller with this Test class,
<?php
use SilverStripe\Dev\FunctionalTest;
class SitePageControllerTest extends FunctionalTest
{
protected static $fixture_file = 'site/tests/fixturesSitePage.yml';
public function testViewSitePage()
{
$obj = $this->objFromFixture('SitePage', 'page1');
$page = $this->get('page-one/');
$this->assertEquals(200, $page->getStatusCode());
}
}
and Fixture.
SitePage:
page1:
Title: Page One
CanViewType: true
But "$this->get('page-one/');" returns a 404 page.
Pages are versioned, and this one isn't published at the point where you ask for it, so the functional test emulates a frontend web request which is served from the live (published) stage by default.
You can use the draft site by appending ?stage=Stage to your request URL, or by using protected static $use_draft_site = true in your functional test (this is deprecated in 4.2).
Note that FunctionalTest doesn't log a user in, so you may also need to log in with some level of permission i.e. $this->logInWithPermission('ADMIN')
Another option is to publish it using something like: $obj->publishRecursive(); before the get()

ASP.NET Unauthorized access on a controller should return 401 instead of 200 and the login page

In an ASP.NET 5 Application I configured MVC and Identity framework like this:
app.UseMvc(config=>{
config.MapRoute("Default", "{controller}/{action}/{id?}", new
{
controller = "Home",
action = "Index"
});
});
and adding Identity Services :
services.AddAuthentication();
services.AddAuthorization();
services.AddIdentity<CrmUser, CrmUserRole>(config => {
config.User.RequireUniqueEmail = true;
})
.AddUserStore<MongoUserStore>()
.AddRoleStore<MongoUserStore>()
.AddDefaultTokenProviders();
and
app.UseIdentity()
.UseCookieAuthentication(i => { i.LoginPath = "/Account/Login";});
The example is defined as this:
public class MyApiController : Microsoft.AspNet.Mvc.Controller
{
[Authorize]
public async Task<ActionResult> Foo()
{
return Ok();
}
}
This works fine, but i also have some controller which I want to use in a API way. In ASP.NET 5, they all have same base class so there is no difference between API and View Controllers.
As a result when calling an unauthorized api which requires authorization, I get an HTTP 200 and the Login page instead of an HTTP 401.
In a blog post by Shawn Wildermuth I found this
services.AddCookieAuthentication(config =>
{
config.LoginPath = "/Auth/Login";
config.Events = new CookieAuthenticationEvents()
{
OnRedirect = ctx =>
{
if (ctx.Request.Path.StartsWithSegments("/api") &&
ctx.Response.StatusCode == 200)
{
ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.FromResult<object>(null);
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
return Task.FromResult<object>(null);
}
}
};
});
But should this really be the expected way to do this? For me this smells a little.
This issue has been fixed in RC1.
Check GitHub comment here: Issue
To upgrade to RC1, go to http://get.asp.net.
To be even more sure, you can also clear your %userprofile%\.dnx\ folder prior to getting the latest version.
One solution to this is send the request with a the following header:
[{"key":"X-Requested-With","value":"XMLHttpRequest"}]
Here is an example using Postman without the header returns 200 and login webpage html
With the header returns 401 and no content (note there is not a tick next to it)
The sample app is based on the ASP.NET Core default solution with Individual User Authentication
Why this works:
CookieAuthenticationEvents.OnRedirectToLogin() uses IsAjaxRequest(context.Request) to decide whether to return a 401 or a redirect. So you have to have a header that will make IsAjaxRequest(context.Request) return true. It appears like a lot of JavaScript libraries add this automatically for you if you call your API through AJAX, but you might be not be using them.
Related questions you might find helpful
ASP.NET MVC - What does IsAjaxRequest() actually mean?
Request.IsAjaxRequest() always returning false in MVC4, tried all suggestions in SO, etc
Detecting IsAjaxRequest() with ASP.NET MVC and JQuery Form Plugin / File Upload
This behaviour was introduced as a result of a request the OP put in (which they mention under the question)
link to the current version of CookieAuthenticationEvents.cs at time of writing.
One (work around) option is to make the coockie options to redirect you to a controller action returning (unauthorized) result
Sorry I'm replying using my phone I'll try to enhance my answer when I'm using my PC...

With Meteor, how to login from remote server?

I'm trying to use 2 servers using DDP.connect.
My subscription works well, but methods called using Meteor.call needs the user to be authenticated.
How can i connect the user to the remote server ?
You can authenticate this way:
var DDPConnection = DDP.connect(<url>);
DDPConnection.call("login", {
"password":"qwerty",
"user" : {
"email":"email#email.com"
}
},
function(err,result) {
//Check result
}
);
Check out my other answer on the different login options depending on the setup you have/want to use.

Using multiple Roots with a Durandal application

Problem:
My application does not start; it just goes into an infinite loop.
Code:
My app.start:
app.start().then(function() {
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//configure routing
router.useConvention();
router.mapNav('home');
router.mapNav('intro');
router.mapNav('error');
router.mapRoute('set/:id', 'viewmodels/set', 'Set');
router.mapRoute('folder/:id', 'viewmodels/folder', 'Folder');
router.mapRoute('api', 'viewmodels/api', 'API Reference');
app.adaptToDevice();
app.setRoot('viewmodels/intro');
//logger.logError('No route found', route, 'main', true);
/*
router.handleInvalidRoute = function (route, params) {
//debugger;
//router.navigateTo('#/error');
};
*/
});
I set the root to intro, which contains a simple viewmodel that has a login function:
define(['durandal/app', 'durandal/plugins/router', 'services/dataservice'], function (app, router, dataservice) {
var introViewModel = function () {
var self = this;
self.router = router;
self.logIn = function () {
app.setRoot('viewmodels/shell');
};
self.activate = function () {
return router.activate('intro');
};
The goal here is to re-set the root of the application if the user is logged in. Any idea what I'm doing wrong?
Based on Rob's answer at the Google Groups page, here are some specifics that worked for me that may help others:
In main.js app.start().then(): set root to be your login page.
After login, configure your router and add routes to it. (Adding
routes must come before router activation.) This is an opportunity
to retrieve only those routes to which the user has access as part of
the login process.
Finally, set app root to be the shell, which then activates the
router with the default route you specify. Currently, I modify the
activate function in router to take an additional parameter of a
start url--that way, I can bypass the default page if need be.
Per Rob over on the Google Groups, I just plucked the router from my intro page and ran it in my shell.js, activating the router only once. This seems to tighten things up a bit and the app is working now:
https://groups.google.com/forum/#!topic/durandaljs/RdGpwIm1oOU
Based on your answer, the first part (setroot to login), I did this but the login page wasn´t loaded, no errors was showed also.
In main I simply put app.setRoot('viewmodels/login', 'entrance');
In login I simply have an activate function:
function activate() {
return true;
}
Is it correct?

PreExecute() function in symfony2

I developed an application using symfony2, I want to know how to write preExecute() function symfony2 for following case:
when I log-in into the system; it redirect me on user profile section when I log-out from same screen, It killed session and redirect me on login screen, but when I hit browser's back button then it will redirect me on profile screen, which shows me all user information but when I click for next process from same screen then I redirect me on login page.
I just want to add preExecute function like symfony1.4 for this case, so I checked session and if it is null then it will redirect me on login page if I hit browser's back button when I alrady log-out from the system.
I already added following code in profileController.php files,
public function indexAction() {
$session = $this->get('request')->getSession();
$userId = $session->get('id');
if ($userId == 0 || $userId == '') {
return $this->redirect($this->generateUrl('_security_login'));
} else {
//my code
}
}
//logout action
public function dologoutAction(){
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$this->container->get('request')->getSession('session')->clear();
return $this->redirect($this->generateUrl('_security_login'));
}
if there is any other way to handle this case then please help me for the same.
Thank you.
Just require the ROLE_USER role on the profile action and the firewall will do the redirect-to-the-login-form-and-then-redirect-back stuff:
/**
* #Secure("ROLE_USER")
*/
public function profileAction()
{
// ...
}
For more information read the Security chapter of the Symfony book.

Resources