Start session when page is loaded in WordPress - wordpress

I want to create a session at the first visit on a page. I can do it, when I'm logged in. So the session get's created when I log in. When i log out, then a new session get's created.
I added to functions.php following code:
/**
* Start Session
*/
function start_session() {
if(session_id) {
session_start();
}
}
add_action('init', 'start_session');
/**
* End Session
*/
function end_session() {
session_destroy ();
}
add_action('wp_logout','end_session');
add_action('wp_login','end_session');

Related

Appmaker: Home Page "AppStart" upon user role

I want the Admin's start page to be the Admin Console and for the user another page - "MyTickets". The default start page for the app is MyTickets but I don't want the Admin to see this as the start page nor be able to navigate to it.
I found in the Appmaker's templates "Training hub" some code for the Appstart depending on the user role, as I want; However, when I implemented it, I get this error in the console
The page keeps loading while in the template it works normally.
Here is the code I inserted in my app in client script:
/**
* Determines whether the user has specified role.
* #param {string} roleName - name of the role to check.
* #return {boolean} true if user has the role.
*/
function hasRole(roleName) {
return (app.user.roles.indexOf(roleName) > -1);
}
/**
* Determines whether the user is admin.
* #return {boolean} true if user is an admin.
*/
function isAdmin() {
return hasRole('Admins');
}
/**
* Gets start page depends on current user's roles.
* #return {Page} start page to be shown to user.
*/
function getUserStartPage() {
var result = app.pages.MyTickets;
var userRoles = app.user.roles;
if (isAdmin()) {
result = app.pages.Admin_console;
}
return result;
}
/**
* Overrides start page if loading is not specified.
* #param {string} currentPageName - name of current page to be loaded.
* #return {Page} start page to be shown to user.
*/
function overrideStartPage(currentPageName) {
if (currentPageName) {
return;
}
var startPage = getUserStartPage();
gotoPage(startPage);
}
/**
* Handles Application Start event.
* Loads Application Settings and then loads the app.
* #param {AppLoader} loader - instance of application loader.
*/
function onAppStart(loader) {
loader.suspendLoad();
google.script.url.getLocation(function(location) {
app.datasources.AppSettings.load({
success: function() {
overrideStartPage(location.hash);
loader.resumeLoad();
},
failure: function() {
overrideStartPage(location.hash);
loader.resumeLoad();
}
});
});
}
And in the app's settings, the startup script is:
onAppStart(loader);
I'd suggest you to dig a bit more into javascript or into the app maker documentation. The solution is very easy but since you are copying and pasting the source code without understanding what is happening, you are having difficulties resolving this matter. Here is the code you need to use:
loader.suspendLoad();
if(app.user.role.Admins){
app.showPage(app.pages.Admin_console);
} else {
app.showPage(app.pages.MyTickets);
}
loader.resumeLoad();
Note Bene: The above code should be used exactly as it is inside the App Settings - App startup script
References: https://developers-dot-devsite-v2-prod.appspot.com/appmaker/scripting/api/client#App

Symfony : how to set init data on login

I'm facing a dilemna as well as an optimization problem :
In my Symfony 2.8 application, I have custom settings and other business logic data to load (from database tables, not from SF parameters) that a logged in user can be needed to use at different pages.
At first those data where scarcely needed, so i loaded them only when the page required it. But now as the application grows, i need them more often.
So i was thinking about loading them when the user logs in, and save them as localStorage on client side because cookies are too small.
But i'm not sure how to best do it.
I have a login success handler, that allows to redirect on the correct page when user is successfully logged.
For the moment i have this one :
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected $router;
protected $authorizationChecker;
public function __construct(Router $router, AuthorizationChecker $authorizationChecker)
{
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
}
/**
* What to do when user logs in.
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$response = null;
if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
//an admin is redirected towards this page
$response = new RedirectResponse($this->router->generate('my_back_admin'));
} else if ($this->authorizationChecker->isGranted('ROLE_USER')) {
//a user is redirected towards this page
$response = new RedirectResponse($this->router->generate('my_back_user'));
}
//redirect to any last visited page if any
$key = '_security.main.target_path';
if ($request->getSession()->has($key)) {
$url = $request->getSession()->get($key);
$request->getSession()->remove($key);
$response = new RedirectResponse($url);
}
return $response;
}
}
So i was thinking about adding a setInitialData() method in which i would get all the settings i need and modifying onAuthenticationSuccess :
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$response = null;
//retrieve array of data to be set in the init
$toBeSaved = $this->setInitialData();
if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
//an admin is redirected towards this page
$response = new RedirectResponse($this->router->generate('my_back_admin', ['initdata'=>$toBeSaved]));
} else if ($this->authorizationChecker->isGranted('ROLE_USER')) {
//a user is redirected towards this page
$response = new RedirectResponse($this->router->generate('my_back_user', ['initdata'=>$toBeSaved]));
}
//redirect to any last visited page if any
$key = '_security.main.target_path';
if ($request->getSession()->has($key)) {
$url = $request->getSession()->get($key);
$request->getSession()->remove($key);
$response = new RedirectResponse($url, ['initdata'=>$toBeSaved]);
}
return $response;
}
And then on the main template, i would retrieve that data
{% for paramName, paramValue in app.request.query %}
{% if paramName == 'initdata' %}
<div id="initdata" data-init="{{paramValue|json_encode}}"></div>
{% endif %}
{% endfor %}
and add a javascript block with something like :
<script>
if ($('#initdata').length > 0){
localStorage.removeItem('initdata');
localStorage.setItem('initdata', JSON.stringify($('#initdata').data('init')));
}
</script>
But this method doesn't seems right : i'm not sure this is the best way to do it.
And furthermore, since these are sent in a redirect, the data are shown in the query string, which is not ideal :(
This will not fly as by having multiple parameters you create multiple <div> elements with identical ID = initdata. Subsequent jQuery selector will only capture the first one (afaik).
I see that you indeed send params via query string. This takes care of multiple value, but this also exposes your user setting in user URL, doesn't it? If it does, it has security vulnerability all over the wall. Remember, such URLs are persisted in your browser's history.
Instead, I suggest you create a separate controller action /_get_user_settings which you will call via AJAX GET. Server will serve JSON response which you can save to your localStorage with little or no problem at all.
Hope this helps...

behat 3 mink testing redirection

In symfony 3 controller file I have function:
/**
* #Route("/user/registration", name="post_registration")
* #Method("POST")
* #return mixed
*/
public function postRegistration()
{
$post = $this->getAllPost();
$this->curl = $this->get('ApiClient');
$responseArray = $this->curl->post(
$this->container->getParameter('api_url') . '/users',
$post
);
if (isset($responseArray['api_key'])) {
return $this->redirectResponseWithCookie($responseArray['api_key']);
} else {
return $this->render(
static::REGISTRATION_TEMPLATE,
['errors' => $responseArray['errors']]
);
}
}
In one part it calls function
redirectResponseWithCookie()
which should redirect the page.
I want to test redirection header - does it have the right Location value.
I have function in UserRegistrationContext class
class UserRegistrationContext extends BaseContext implements Context, SnippetAcceptingContext
{
/**
* #When I register successfully into the system
* #return null
*/
public function iRegisterSuccessfullyIntoTheSystem()
{
$this->canIntercept();
$this->session->getDriver()->getClient()->followRedirects(false);
// Enters his data
// Posts to www.notification.guru .
$this->session->getDriver()->getClient()
->request('POST', $this->baseUrl . '/user/registration', $this->getFormArray());
echo 'test';
}
}
BaseContext class just has some helper functions, its contructor inits session:
$driver = new GoutteDriver();
$this->session = new Session($driver);
this part might be wrong:
$this->session->getDriver()->getClient()->followRedirects(false);
I just took code from behat 2.5 and tried to adjust to work it with behat 3, but not sure if its correct, but at least does not throw error.
It should stop redirect, so then I could get a response header with
getResponseHeaders()
But the problem is that it tries to redirect, and code fails, because real site is not lauched yet where it redirects. And also I would not be able to test headers I guess after real redirection.
So the redirection has to be stopped I guess.
How to do that? I cannot find info.
Test fails at line
$this->session->getDriver()->getClient()
->request('POST', $this->baseUrl . '/user/registration', $this->getFormArray());
So code in my question is not wrong, as I said in comment - I did not see well in console. Often happens that when I post to SO, I do not even finish writing the question, just from writing the details to others I see the answer.
$this->session->getDriver()->getClient()->followRedirects(false);
works well.
So to finish how to check - make function something like this and call it:
/**
* #param Behat\Mink\Session $session - mink session
* #throws \Exception
* #return null
*/
public function isLoggedIntoApi($session)
{
$headers = $session->getResponseHeaders();
if ($headers['Location'][0] != $this->appUrl) {
throw new \Exception(
'User is not redirected to ' . $this->appUrl
);
}
}

Detect first FOSFacebookBundle login

I implemented successfully the FOSFacebookBundle with the FOSUserBundle. Everything works great.
Now, I'd like to be able to detect the first connection of an user with the FOSFacebookBundle.
I have a FacebookAuthenticationSuccessHandler which is called every time a Facebook authentication successes, but I'd like to declare a kind of "FirstFacebookAuthenticationSuccessHandler", called only if the user didn't exist yet. The goal of this handler is to be able to send a welcome email to each new user.
For the classic registration, I simply use a RegistrationSuccessListener.
Do you have any idea on how I could do this?
Answering my own question as I found the solution.
1/ I created (and registered) a new event listener called NewFacebookUserListener:
...
/**
* {#inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
MyCustomEvents::NEW_FACEBOOK_USER => 'onNewFacebookUser'
);
}
public function onNewFacebookUser(UserEvent $event)
{
// we get the user
$user = $event->getUser();
// and now you can do what you wish
}
2/ In my FacebookProvider (located under Security/User/Provider), I added a few lines to dispatch this new event:
$user->setFBData($fbdata);
// we send a "FB user created" event
$dispatcher = $this->container->get('event_dispatcher');
$dispatcher->dispatch(MyCustomEvents::NEW_FACEBOOK_USER, new UserEvent($user, $this->container->get('request')));
And as expected, the event is dispatched only when a new Facebook user is created.

Failing to redirect from JSF phaselistener

My problem is similar to the one here but doesn't involve PrimeFaces in any way. Also, I couldn't find a real solution there.
I'm basically trying to get the phaselistener to redirect to login page in case there is no JSF session (When, for example, session has timed out)
I'm trying to redirect from within a JSF 2 Phaselistener. To sum up, what I'm doing is this:
public void beforePhase(PhaseEvent event) {
PhaseId id = event.getPhaseId();
if(id.equals(PhaseId.RESTORE_VIEW)){
FacesContext context = event.getFacesContext();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
if(sessionMap==null || sessionMap.isEmpty()){
// No Session, Redirect to login
try {
context.getExternalContext().redirect("/login");
} catch (Exception e) {
...
}
}
}
}
When the redirect code runs I get this exception:
java.lang.NullPointerException
at org.apache.myfaces.context.servlet.PartialViewContextImpl.getPartialResponseWriter(PartialViewContextImpl.java:301)
at org.apache.myfaces.context.servlet.ServletExternalContextImpl.redirect(ServletExternalContextImpl.java:452)
at com.AuthenticationPhaseListener.userIsNotLogedIn
What could be causing this? Am I doing this wrong?
Thanks!
This seem to be happening during an ajax request. I'm not sure about the exact cause, the stacktrace at least indicates a possible bug in MyFaces implementation.
At least, the overall design approach is poor. This kind of HTTP request/response modifications should preferably not take place in a PhaseListener. There it is not intended for. You want to do this kind of job in a normal servlet Filter instead.
Well I had the same problem like you but I did not solve in in such a complicated way as you are doing.My steps
1) create a class that implements the PhaseListener
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
/**
*
* #author fakumawah #date 09.03.2012
*/
public class LoggedInCheck extends BackingBean implements PhaseListener
{
#Override`enter code here`
public PhaseId getPhaseId()
{
return PhaseId.ANY_PHASE;
}
#Override
public void beforePhase(PhaseEvent event)
{
}
#Override
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
boolean loginPage = fc.getViewRoot().getViewId().lastIndexOf("login") > -1 ? true : false;
if (!loginPage && !loggedIn())
{
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, "gotologin");
}
}
private boolean loggedIn()
{
return getSessionWrapper().isLoggedInAgain();
}
}
Sorry for the uncommented code but I guess the code is really easy to understand. Most important thing to note is the afterPhase(..) which checks if I am in the logged in or if I have a session already. If I donĀ“t it creates a navigator and navigates me to the login page
2) Your isLoggedInAgain() should look something like this:
/**
* A method to check if Username is already logged in
* #param username
* #return
*/
public boolean isLoggedInAgain()
{
if (session != null) // Check if session is not null
{
if (session.isConnected()) // Check if session is connected
{
return true;
//destroyIfsLibrarySession(); // Session is available -> destroy session
}
else // session is not available
{
logger.log(Level.SEVERE, "Already logged out");
return false;
}
}
return false;
}
Since I am dealing with LibrarySessions from Oracle CMSDK that is why my test for the session looks like this. Most important is to check your session somehow and give out true or false, depending on if session exist or not.
3) Configure the Listener in faces-config.xml
<!-- Phase-Listener to check if user is logged in or not -->
<lifecycle>
<phase-listener>com.mycompany.mypackagename.webapp.LoggedInCheck</phase-listener>
</lifecycle>
4) Lastly define a navigation rule for the "gotologin"
<!-- Navigation Rule for sending user to login page from an expired session -->
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>gotologin</from-outcome>
<to-view-id>/login.em</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
And that is it, whenever you do not have a session on any page and are not on the login page, you will be carried to the login page.
Enjoy

Resources