Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Dave Kliczbor
How to set Default Landing Page via custom LoginPostAction?
November 29, 2011 8:28 AM
Answer

Dave Kliczbor

Rank: Junior Member

Posts: 65

Join Date: July 12, 2011

Recent Posts

Hello there!

I keep getting a strange behaviour while deploying a custom LoginPostAction. On my local machine (WinXP32bit/HSQL/Java1.6/Tomcat7/Liferay6.1.0-b3) it works perfectly. On our test server (Linux/Java1.6/OracleDB/Tomcat7/Liferay6.1.0-b3) it deploys without error, but on login it results in an infinite loop (i.e. no page content is delivered, Tomcat draws 200% CPU). Curiously, I am logged in afterwards: directly entering a URL works while Tomcat still draws 200% CPU. Println-Debugging to catalina.out just showed that my custom class has been called and the infinite loop does not come up in my class. The configuration does not differ much between these two Liferay instances; they're mostly database related and a few third-party plugins are installed which would not work on my machine (they access a DB that's out of my reach).

Okay, my approach looks like this:
  1. I created a new Hook Plugin in Liferay IDE
  2. I added a new class: com.liferay.portal.events.CustomLoginPostAction (I tried other package paths, too). For this, I started with Tarkan Corak's "Login Landing Page Hook" for LR 6.0.5+ and modified it to my needs:
      1/**
      2 * Copyright (c) 2010 Tarkan Corak. All rights reserved.
      3 * Modified (2011) by Dave Kliczbor.
      4 *
      5 * This library is free software; you can redistribute it and/or modify it under
      6 * the terms of the GNU Lesser General Public License as published by the Free
      7 * Software Foundation; either version 2.1 of the License, or (at your option)
      8 * any later version.
      9 *
     10 * This library is distributed in the hope that it will be useful, but WITHOUT
     11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     12 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
     13 * details.
     14 *
     15 * Changelog:
     16 *         Added code for redirecting the user to the private page set by
     17 *         default.user.private.layout.friendly.url in portal-ext.properties
     18*/
     19
     20package com.liferay.portal.events;
     21
     22import java.util.List;
     23
     24import javax.servlet.http.HttpServletRequest;
     25import javax.servlet.http.HttpServletResponse;
     26import javax.servlet.http.HttpSession;
     27
     28import com.liferay.portal.kernel.events.Action;
     29import com.liferay.portal.kernel.events.ActionException;
     30import com.liferay.portal.kernel.log.Log;
     31import com.liferay.portal.kernel.log.LogFactoryUtil;
     32import com.liferay.portal.kernel.struts.LastPath;
     33import com.liferay.portal.kernel.util.PropsKeys;
     34import com.liferay.portal.kernel.util.PropsUtil;
     35import com.liferay.portal.kernel.util.WebKeys;
     36import com.liferay.portal.model.Group;
     37import com.liferay.portal.model.Organization;
     38import com.liferay.portal.model.User;
     39import com.liferay.portal.service.UserLocalServiceUtil;
     40import com.liferay.portal.util.PortalUtil;
     41
     42public class CustomLoginPostAction extends Action {
     43
     44    /**
     45     * Will be fired for each Login Event and redirects the user to her or his landing page.
     46     */
     47    public void run(HttpServletRequest request, HttpServletResponse response)
     48            throws ActionException {
     49
     50        try {
     51            debug("CustomLoginPostAction for User: " + request.getRemoteUser());
     52
     53            HttpSession session = request.getSession();
     54            User user = UserLocalServiceUtil.getUser(PortalUtil.getUserId(request));
     55            LastPath lastPath = null;
     56            Group firstUserGroup = null;
     57
     58            // First look for User's Private Pages
     59            if(user.hasPrivateLayouts()) {
     60                debug("Redirect to User's Private Pages");
     61                lastPath = new LastPath(
     62                        request.getContextPath(), 
     63                        PropsUtil.get(PropsKeys.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING)
     64                            + user.getGroup().getFriendlyURL()
     65                            + PropsUtil.get(PropsKeys.DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL)
     66                    );
     67            }
     68
     69            if(lastPath == null) {
     70                // Look for Organizations
     71                debug("Looking for associated Organizations");
     72                List<Organization> organizations = user.getOrganizations();
     73                for(Organization organization : organizations) {
     74                    Group group = organization.getGroup();
     75                    debug("Organization: " + group.getName()
     76                            + ", friendlyUrl: " + group.getFriendlyURL());
     77                    if(firstUserGroup == null)
     78                        firstUserGroup = group;
     79                    if(group.hasPrivateLayouts()) {
     80                        lastPath = new LastPath(request.getContextPath(), PropsUtil.get(PropsKeys.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING)+group.getFriendlyURL());
     81                        debug("Redirect to Organization's Private Pages");
     82                    }
     83                    if(lastPath != null)
     84                        break;
     85                }
     86            }
     87
     88            if(lastPath == null) {
     89                // Look for Communities
     90                debug("Looking for associated Communities");
     91                List<Group> groups = user.getGroups();
     92                for(Group group : groups) {
     93                    debug("Community: " + group.getName() + ", friendlyUrl: "
     94                            + group.getFriendlyURL());
     95                    if(firstUserGroup == null)
     96                        firstUserGroup = group;
     97                        if(group.hasPrivateLayouts()) {
     98                            debug("Redirect to Organization's Private Pages");
     99                            lastPath = new LastPath(request.getContextPath(), PropsUtil.get(PropsKeys.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING)+group.getFriendlyURL());
    100                        }
    101                        if(lastPath != null)
    102                            break;
    103                }
    104            }
    105
    106            if(lastPath == null && firstUserGroup != null) {
    107                // Redirect to the Public Pages of the first found
    108                // Community/Organization
    109                debug("Redirect to Community/Organization's Public Pages");
    110                lastPath = new LastPath(request.getContextPath(), PropsUtil.get(PropsKeys.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING)+firstUserGroup.getFriendlyURL());
    111            }
    112
    113            if(lastPath != null) {
    114                debug("lastPath = " + lastPath.toString());
    115                session.setAttribute(WebKeys.LAST_PATH, lastPath);
    116            }
    117        } catch (Exception e) {
    118            throw new ActionException(e);
    119        }
    120    }
    121
    122    private void debug(String msg) {
    123        System.out.println("CustomLoginPostAction: " + msg);
    124    }
    125}
  3. I added a portal.properties for the plugin:
    1auth.forward.by.last.path=true
    2login.events.post=com.liferay.portal.events.CustomLoginPostAction
    and registered it via liferay-hook.xml:
    1<?xml version="1.0"?>
    2<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd">
    3
    4<hook>
    5    <portal-properties>portal.properties</portal-properties>
    6</hook>

I always get the same debug messages, varying only in the user id (in this case: the user with the screenname "test" and id 10202):
1CustomLoginPostAction: CustomLoginPostAction for User: 10202
2CustomLoginPostAction: Redirect to User's Private Pages
3CustomLoginPostAction: lastPath = {contextPath=, path=/user/test/home}

And yes, I read various articles on this topic.

Where did I go wrong? Is there a more stable approach to this? All I'm trying to do is to redirect the users to their private profile page (and in the future I need to check their groups too -- members of one special group should be redirected to a different specific page, so I'll definitely need to inject my own code).
David H Nebinger
RE: How to set Default Landing Page via custom LoginPostAction?
November 30, 2011 6:19 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11770

Join Date: September 1, 2006

Recent Posts

The only difference I see in how you create the last path and how mine works, I always pass StringPool.BLANK as the first argument...
Samir Gami
RE: How to set Default Landing Page via custom LoginPostAction?
November 30, 2011 9:30 PM
Answer

Samir Gami

Rank: Regular Member

Posts: 162

Join Date: February 3, 2011

Recent Posts

Yes, I am agree with David, I am also passing the BLANK as first argument
This may help -- http://www.liferay.com/community/forums/-/message_boards/message/10771919
Dave Kliczbor
RE: How to set Default Landing Page via custom LoginPostAction?
December 1, 2011 7:13 AM
Answer

Dave Kliczbor

Rank: Junior Member

Posts: 65

Join Date: July 12, 2011

Recent Posts

Thanks for the answers, guys... but it did not have anything to do with this. Not even with the login process. It's been a facepalm issue where you simply don't have enough hands to justify the situation.

I always logged in via the default user (admin) to test my plugin. Because of Liferay's method to copy the user's public and private pages from a template, this user had an old set of layouts. The default layout in the private layoutset of this user was existent -- BUT: it linked back to itself, although it was of type 'portlet'. It even had itself as parent. And it was hidden. I don't know who did what to make it this way (I'm not the only one working on this test server), but setting it's PARENTID in the table LAYOUT to 0 and removing the "linktolayout" line in the TYPESETTINGS column solved the issue.

I cannot imagine that someone set this directly in the DB (I know the other's, they either don't want to meddle with a DB or are knowledgeable enough to do it right), but as far as I know, there is no way in the GUI to set it this way. What on earth went wrong here? (rhetorical question, but it would be interesting)