Magento post from controller - forms

Lately I've been using cURL to post data back from a custom Magento controller to a custom page on the same website.
However, the way I do it somehow breaks Magento's log in data. So I've tried another way. Magento has cURL functionality built into it (Varien_Http_Adapter_Curl).
I've tried to Post through this, but so far it has been over my head and documentation on the web is fairly sparse. I need help with this. I've got a string with all the $_POST data ready to go. Please can someone tell me how to send it?
This:
$url="<URL>";
$curl = new Varien_Http_Adapter_Curl;
$curl->setConfig(array('timeout' => 15));
$curl->write(Zend_Http_Client::POST,$url, '1.1', array(), $poststring);
$result = $curl->read();
$curl->close();
...isn't sending data .
Edit:
I've tried the non-Magento cURL, but didn't know about session Data. I still have no Idea how to send session data, either.
Now, I've tried session variables, but the result is that I can set and extract data on one page, but when changing pages the data is lost. So, this can't be used currently between the controller and view.

better you can use the magento sessions
http://magento-rohan.blogspot.in/2012/03/magento-get-set-unset-session.html
here is this how to use it

You need to give us more information about what are you trying to achieve. Basically you need to tell us where are you sending POST request to? Perhaps another Magento instance or even same Magento website? Are you expecting user to have same session it is having now? Once you give us more info I will edit my answer. For now I will try to guess what is bothering you based on the input you gave.
When you are submitting POST request with curl from server side, that means that user is no longer interacting with the "page" you are trying to submit post request to.
If user is not interacting with it, that means it is not sending user session information.
Basically it looks like this:
Normally
Eric ->(Request with session info)-> Server (Oh it's you Eric, here is
the response just for you)
What are you trying to do
Eric ->(Request with session info)-> Server ->(Request without session
info)-> Server (This server doesn't know about Eric)
So to implement this correctly, if I am good at assuming what is your problem, just pass session information to the second server along with your request.
I will add more info if you tell me I am on the good track of understanding your problem.
---UPDATE---
You didn't explain your situation well. I am telling you this because your whole approach with the cURL may be bad decision from the start. For example, if you are trying to execute code in the same Magento codebase and that code is trapped inside some controller, perhaps you can refactor your code and encapsulate that logic inside some model and execute it directly.
But here is the example of passing session information over curl in plain php:
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
curl_setopt( $curl, CURLOPT_COOKIE, $strCookie );
Cookie should perhaps be called "frontend" in Magento. And I checked Varien_Http_Adapter_Curl it doesn't have any method for seting CURLOPT_COOKIE option so I suggest you go with plain curl setup. You also have an option to extend adapter and add that option by your self. Just override "_applyConfig" method.

Related

.HttpContext.User is null after successful login from SAML Identity Provider?

Trying to retrofit an old webforms application.
Got my configuration working so that it's prompting for login and successfully redirecting back to the application. The folks that manage the IP can see the response is generated.
However in the callback to my application the User is null. I'm told if it's configured correctly it should be populated.
We have a custom IHttpModule and that is where I can see getting hit with the call to /Saml2/Acs with the User not populated. I think this may be expected as the handler for that is supposed to populate the User, I think? However the following call (the returnUrl configured in sustainsys.Saml2) still has no User and I don't see any sort of error or anything.
Anyone with experience have an idea how to debug this?
The call to /Saml2/Acs should be taken care of by the Sustainsys.Saml2.HttpModule. It will process the response and then call the SessionAuthenticationModule to set a cookie that preservers the User across calls.
To get some more information about what's happening in the library, you can assign an implementation of ILoggerAdapter to Sustainsys.Saml2.Configuration.Options.FromConfiguration.SPOPtions.Logger to get some logging output from the library.
My issue turned out to be that I had another authentication module loaded before SessionAuthenticationModule and Saml2AuthenticationModule in the web config.
The comment in the example was
Add these modules below any existing. The SessionAuthenticatioModule
must be loaded before the Saml2AuthenticationModule
However in my case with I had another authentication module involved that needed to go last.

JSON Request is not configure with zap Authentication.

I am using ZAP security testing tool.but at the point of Authentication by username and password of a JSON Request, I face problem to configure these. I checked all links and blogs too. but I can't get the proper step by step solution on it.
Request code:-
{"userName":"cwc_patna","password":"33a0d2e93e0ad396b7c9374bbbc83a58"}
Response code:-
{"userId":72,"userName":"cwc_patna","password":"33a0d2e93e0ad396b7c9374bbbc83a58","emilId":"pratyush#sdrc.co.in","userTypeId":1,"viewName":"cwc","isLive":null,"isActive":null,"isApproved":null,"sjpuAccess":null,"userUserTypeFeaturePermissionMapping":null,"area":null}
That functionality was only just added last week: https://github.com/zaproxy/zaproxy/pull/4624
If you want to use it, you'll either have to use a weekly: https://github.com/zaproxy/zaproxy/wiki/Downloads#zap-weekly
Or, wait for the next full release (likely 2.8.0).
The corresponding PR to update the help content for the new JSON Authentication functionality is here: https://github.com/zaproxy/zap-core-help/pull/188/files if you want to check it out.
You set it up the same way you would for form based authentication. Make sure you define a Logged-in or Logged-out Identifier (or both). Here's some screenshots to help you along:
Manually configure the Authentication for your Context:
Use the Site Tree Context menu(s) to set it up:
Here's an additional help link that might assist you in getting authentication setup: https://github.com/zaproxy/zaproxy/wiki/FAQformauth

Real time model events in Sails.js 0.10-rc5

I've been playing around with building some realtime functionality using Sails.js version 0.10-rc5 (currently the #beta release).
To accomplish anything, i've been following the sweet SailsCast tutorial on this subject (sailsCast link)
It talks about subscribing to a model via a 'subscribe' action within the model's controller. Then listening to it at the client side, waiting for the server to emit messages. Quite straightforward, although I do not seem to receive any messages.
I'm trying to do this to get real-time updates on anything that changes in my User models, or if new ones get created.. So I can display login status etc. in real time. Pretty much exactly the stuff that's explained in the sailsCast.
In my terminal i'll get two things worth noticing, of which the first is the following:
debug: Deprecated: `Model.subscribe(socket, null, ...)`
debug: See http://links.sailsjs.org/docs/config/pubsub
debug: (⌘ + double-click to open link from terminal)
debug: Please use instance rooms instead (or raw sails.sockets.*() methods.)
It seems like the 'subscribe' method has been deprecated. Could anybody tell me if that's correct, and tell me how to fix this? I've been checking out the reference to the documentation in the debug message, although it just points me to the global documentation page. I've been searching for an answer elsewhere, but haven't found anything useful.
The second message I'm getting is:
warn: You are trying to render a view (_session/new), but Sails doesn't support rendering views over Socket.io... yet!
You might consider serving your HTML view normally, then fetching data with sockets in your client-side JavaScript.
If you didn't intend to serve a view here, you might look into content-negotiation
to handle AJAX/socket requests explictly, instead of `res.redirect()`/`res.view()`.
Now, i'm quite sure this is because I have an 'isAuthenticated' policy added to all of my controllers and actions. When a user is not authenticated, it'll redirect to a session/new page. Somebody must log in to be able to use the application. When I remove the 'isAuthenticated' policy from the 'subscribed' action, the warnings disappear. Although that means anyone will get updates via sockets (when I get it to work), even when they're logged out. - I don't really feel like people just sitting at the login screen, fishing out the real time messages which are intended only for users who are logged in.
Can anyone help me getting the real time updates to work? I'd really appreciate!
As far as the socket messages not being received, the issue is that you're following a tutorial for v0.9.x, but you're using a beta version of Sails in which PubSub has gone through some changes. That's covered in this answer about the "create" events not being received.
Your second issue isn't about sockets at all; you'll just need to reconsider your architecture a bit. If you want to to use socket requests to sign users in, then you'll have to be more careful about redirecting them because, as the message states, you can't render a view over a socket. Technically you could send a bunch of HTML back to the client over a socket, and replace your current page with it, but that's not very good practice. What you can do instead is, in your isAuthenticated policy, check whether the request is happening via sockets (using req.isSocket) and if so, send back a message that the front end can interpret to mean, "you should redirect to the login page now". Something like:
module.exports = function (req, res, next) {
if ([your auth logic here]) {
return next();
}
else {
if (req.isSocket) {
return res.json({status: 403, redirectTo: "/session/new"});
} else {
return res.redirect("/session/new");
}
}
}

MVC 2.0 Post Form to action instead of redirect to action

I am using T4MVC to redirect to another action return RedirectToAction(MVC.MyController.MyAction());.
In result it is doing get request.
Is there any way to make post request from controller. I want to keep all the same but only make post instead get. I cant find any methods for that. I found one post helper here http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx but i cant pass any values i need using this post helper. I was trying to pass values through TempData but they are not coming when i using this helper. May be some one have any ideas?
The reason i want to do this because when user come from one controller to another and then if user click update or just click enter in browser address bar, page will break.
Should i use session for that reason?
A RedirectToAction will always perform a GET, never a POST (it returns a HTTP 302 to the browser, which will then issue a GET request).
To persist data across the redirect, if it is data that can be easily represented as a string and stored in the query string, then you can just add it to the route values of the redirect.
e.g.
return RedirectToAction("Search", new { searchString = "whatever" });
If it is a complex type, then you will need to store it in TempData. A number of other questions on StackOverflow (such as this one) give details on how.
If repeatedly storing to and reading from TempData across your application offends your code-sense, then you can encapsulate this by using the PassParametersDuringRedirect attribute and generic RedirectToAction available in the MvcContrib project. Some details on this technique are available here.
only way of doing post is by having a form and doing submit on that form, either with a submit button or with javascript, any info you want passed to that action must be in that form and you will find everything posted in FormCollection(hope I spelled it right).

What's the best action persistence technique for a Catalyst application?

I'm writing a Catalyst application that's required to have a fairly short session expiration (15 minutes). I'm using the standard Catalyst framework authentication modules, so the user data is stored in the session -- i.e., when your session expires, you get logged out.
Many of the uses of this application will require >15 minutes to complete, so users will frequently submit a form only to find their session state is gone and they're required to log back in.
If this happens I want to preserve the original form submission, and if they log in successfully, continue on and carry out the form submission just as if the session had not expired.
I've got the authentication stuff being handled by an auto() method in the controller -- if you request an action that requires authentication and you're not currently logged in, you get redirected to the login() method, which displays the login form and then processes it once it's submitted. It seems like it should be possible to store the request and any form parameters when the auto method redirects to the login(), and then pull them back out if the login() succeeds -- but I'm not entirely sure of the best way to grab or store this information in a generic/standard/reusable way. (I'm figuring on storing it in the session and then deleting it once it's pulled back out; if that seems like a bad idea, that's something else to address.)
Is there a standard "best practices" or cookbook way to do this?
(One wrinkle: these forms are being submitted via POST.)
I can't help thinking that there's a fundamental flaw in mandating a 15 minute timeout in an app that routinely requires >15 minutes between actions.
Be that as it may, I would look at over-riding the Catalyst::Plugin::Session->delete_session method so that any contents of $c->request->body_parameters are serialised and saved (presumably to the database) for later recovery. You would probably want some rudimentary check of the POST arguments to ensure they're what you're expecting.
Similarly, create_session needs to take responsibility for pulling this data back out of the database and making it available to the original form action.
It does seem like a messy situation, and I'm inclined to repeat my first sentence...
UPDATE:
Whether you use delete_session or auto, the paradoxical issue remains: you can't store this info in the session because the time-out event will destroy the session. You've got to store it somewhere more permanent so it survives the session re-initialization. Catalyst::Plugin::Session itself is using Storable, and you should be able to with something along these lines:
use Storable;
...
sub auto {
...
unless (...) { #ie don't do this if processing the login action
my $formitems = freeze $c->request->body_parameters;
my $freezer = $rs->update_or_create(
{user => $c->user, formitems => $formitems} );
# Don't quote me on the exact syntax, I don't use DBIx::Class
}
...
my $formitems = $c->request->body_parameters
|| thaw $rs->find({$user => $c->user})->formitems
|| {} ;
# use formitems instead of $c->request->body_parameters from here on in
The underlying table probably has (user CHAR(x), formitems TEXT) or similar. Perhaps a timestamp so that nothing too stale gets recovered. You might also want to store the action you were processing, to be sure the retrieved form items belong to the right form. You know the issues for your app better than me.
I would store the form data as some sort of per user data in the model.
Catalyst::Plugin::Session::PerUser is one way of doing that (albeit somewhat hackishly). I would reccomend using the session plugin only for authentication and storing all the state info in the model that stores your user data instead.
And I totally agree with RET's opinion that the 15 minute limit seems really counter productive in this context.
I came across this whilst searching CPAN for something entirely unrelated.
Catalyst::Plugin::Wizard purports to do exactly what you need. The documentation suggests it can redirect to a login page whilst retaining the state of the previous action.
NB: I haven't used it, so can't vouch for its effectiveness.
In the end, we ended up grabbing the pending request (URL+params) in the auto(), serializing and encrypting it, and passing it via a hidden form element on the login page. If we got a login request with the hidden element populated, we decrypted and deserialized it and then redirected appropriately (making sure to pass through the standard "can this user do this thing" code paths).
You could always have some javascript on the client that keeps the session from expiring by making a small request every few minutes.
Or you could have AJAX check for an active session before posting the form and presenting the user with a new login box at that time if needed.