How to get portlet context in config (Liferay)? - liferay

I'd like to access the Context of the portlet in config mod (in my implement of ConfigurationAction interface).
I try since hours to get the same Context in my ConfigurationActionImpl.processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) as I have in my doView(RenderRequest renderRequest, RenderResponse renderResponse), but without any good result.
In my doView(), I can access my portlet Context using getPortletContext() (same as getPortletConfig().getPortletContext()) and renderRequest.getPortletSession() (it's NOT the same Context instances), but I don't know how I can access one of those objects from my processAction().
Can somebody help me, please ?

This is the method I ended up using:
PortletBag portletBag = PortletBagPool.get(portletId);
DispatcherPortlet portlet = (DispatcherPortlet)portletBag.getPortletInstance();
PortletContext pCtx = portlet.getPortletContext();
In case you want to compute the portletId, you can do this:
String portletResource = ParamUtil.getString(renderRequest, "portletResource");
String portletId;
if (portletResource.contains("_INSTANCE")) {
portletId = portletResource.substring(0, portletResource.indexOf("_INSTANCE"));
} else {
portletId = portletResource;
}
As a side note, I want to mention that I needed it in order to be able to get the Spring ApplicationContext of the portlet, which I did with this:
PortletContext pCtx = portlet.getPortletContext();
ApplicationContext portletAppContext = (ApplicationContext)pCtx.getAttribute(FrameworkPortlet.PORTLET_CONTEXT_PREFIX + portlet.getPortletName());

Related

Liferay Action Hook: how to specify a tiles redirect?

I create a Liferay 6.2 hook by following official documentation, and everything works fine.
Now I need that, in the render phase and under several conditions, my user will be redirect to a specific tiles.
Original Liferay render method says:
return actionMapping.findForward("portlet.journal.error");
By the way in my class (extending BaseStrutsPortletAction) the render method can't access to any actionMapping instance.
So... how can I obtain the same behaviour in my class?
My code says:
#Override
public String render(
StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, RenderRequest renderRequest,
RenderResponse renderResponse)
throws Exception {
Boolean myCondition = .......;
if (myCondition) {
// WHAT SHOULD I DO HERE?
//return actionMapping.findForward("portlet.journal.error");
}
return originalStrutsPortletAction.render(
null, portletConfig, renderRequest, renderResponse);
}
Thank you
All you need is to return the forward name.
Instead of actionMapping.findForward("portlet.journal.error"), return just "portlet.journal.error".
BaseStrutsPortletAction#render method is called from com.liferay.portal.struts.PortletActionAdapter#render, which uses the result to call actionMapping.findForward(...).

Customize CreateAccountAction in Liferay Portal

I'm trying to add "User Group" Selection field while creating a user (Self User Registration form - create_account.jsp).
Here Custom fields is not helpful because Usergroup is already exists in db. I want to insert into existing Users_UserGroups table.
I'm using below hook:
But User is not added in the group and no exception is printed.
Please suggest me for any other way to achieve this.
public class CustomCreateAccountAction extends BaseStrutsPortletAction
{
public void processAction(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception
{
System.out.println("My Custom Process Action Method is Called");
String emailid=ParamUtil.getString(actionRequest, "emailAddress");
long[] userGroupIds = null;
originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest,actionResponse);
System.out.println("This is after user is registered");
if (SessionErrors.isEmpty(actionRequest))
{
ThemeDisplay themeDisplay =(ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
long newlyCreatedUserId=UserLocalServiceUtil.getUserIdByEmailAddress(themeDisplay.getCompanyId(), emailid);
long userIds[]={newlyCreatedUserId};
long dummygroupid=16206;
System.out.println("TEST UserID="+newlyCreatedUserId);
System.out.println("TEST GroupID="+dummygroupid);
//Everything went well until here.
UserServiceUtil.addUserGroupUsers(dummygroupid, userIds);
//below sysout is not printed. and no exception or user in group db created.
System.out.println("user added to group");
}
}
public String render(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception
{
System.out.println("My Custom Render Method is Called");
return originalStrutsPortletAction.render(null, portletConfig, renderRequest, renderResponse);
}
}
for more info please have a look at this thread.
Using UserLocalServiceUtil instead of UserServiceUtil worked. Basically, the difference is that *ServiceUtil checks permissions and *LocalServiceUtil does not.
I'm not sure this is the best idea, but you can use the hook for both modify the user creación jsp and save the value via model listener on user create/modify.
Regsrds

Liferay Hook - Manipulation request parameters

I ran into a little problem with a hook. Szenario:
The Hook should override struts action /document_library/edit_file_entry which is called, whenever a user uploads a document into the document library.
The goal is to check the title of the document and rename it following a given naming-scheme.
My solution:
#Override
public void processAction(
StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse)
throws Exception {
//Get old title - set new title
String oldTitle = ParamUtil.getString(actionRequest, "title");
String newTitle = "Test";
//wrap request to set param
DynamicActionRequest actionRequestNew = new DynamicActionRequest(actionRequest);
actionRequestNew.setParameter("title", newTitle );
//call original struts action with modified title
originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequestNew, actionResponse);
}
The Problem is that the original Struts action in portal-impl/src/com/liferay/portlet/documentlibrary/action/EditFileEntryAction.java uses PortalUtil.getUploadPortletRequest(actionRequest); which expects a PortletRequestImpl.
But DynamicActionRequest cannot be cast to PortletRequestImpl.
See:
12:07:04,466 ERROR [http-bio-8082-exec-44][render_portlet_jsp:154] java.lang.ClassCastException: com.liferay.portal.kernel.portlet.DynamicActionRequest cannot be cast to com.liferay.portlet.PortletRequestImpl
at com.liferay.portal.util.PortalImpl.getUploadPortletRequest(PortalImpl.java:4067)
at com.liferay.portal.util.PortalUtil.getUploadPortletRequest(PortalUtil.java:1253)
at com.liferay.portlet.documentlibrary.action.EditFileEntryAction.updateFileEntry(EditFileEntryAction.java:653)
at com.liferay.portlet.documentlibrary.action.EditFileEntryAction.processAction(EditFileEntryAction.java:129)
at com.liferay.portal.struts.StrutsPortletActionAdapter.processAction(StrutsPortletActionAdapter.java:51)
at com.liferay.portal.kernel.struts.BaseStrutsPortletAction.processAction(BaseStrutsPortletAction.java:42)
at com.foo.hook.portlet.sites.action.MyEditFileEntryAction.processAction(MyEditFileEntryAction.java:83)
at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
at com.liferay.portal.struts.PortletActionAdapter.processAction(PortletActionAdapter.java:55)
at com.liferay.portal.struts.PortletRequestProcessor.process(PortletRequestProcessor.java:169)
at com.liferay.portlet.StrutsPortlet.processAction(StrutsPortlet.java:212)
at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:70)
at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:48)
at com.liferay.portlet.InvokerPortletImpl.invoke(InvokerPortletImpl.java:548)
at com.liferay.portlet.InvokerPortletImpl.invokeAction(InvokerPortletImpl.java:579)
at com.liferay.portlet.InvokerPortletImpl.processAction(InvokerPortletImpl.java:294)
at com.liferay.portal.action.LayoutAction.processPortletRequest(LayoutAction.java:944)
at com.liferay.portal.action.LayoutAction.processLayout(LayoutAction.java:688)
at com.liferay.portal.action.LayoutAction.execute(LayoutAction.java:249)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
How can I change the parameter without using DynmicActionRequest? Any suggestions?
I'm running Liferay-Portal 6.1.20 EE.
Thanks in advance.
There are two approaches I can think of.
1) Create ActionRequestWrapper object and add a parameter. This would probably solve your issue.
2) Create a subclass of LR's action class. In that make the needed code changes. Create a hook and make the new action class available to LR.
I hope this helps.
You can set the parameter in existing actionRequest:
actionRequest.setParameter("title", newTitle);
It will updated with new value.

Configure Apache Shiro to load [urls] section fully from JPA Entities

I can't seem to find an example to load the [users] AND [urls] from my JPA objects.
I want to use shiro.ini for [main] section only.
The source code of what I achieved so far is this:
Unable to #Inject my DAO in a Custom Apache Shiro AuthorizingRealm
Is there any example where [users] (user/pass) AND [urls] (roles, permissions) are FULLY loaded from database? I can't seem to find that anywhere. I'm looking for it for 1 week now.
After some long research, the "best" solution I came up with was this:
shiro.ini
[main]
jsfFilter = com.test.security.CustomAuthorizationFilter
jsfFilter.loginUrl = /login.jsf
[urls]
/** = jsfFilter
// You can add the methods to filter Ajax requests described by BalusC inside this filter.
CustomAuthorizationFilter.java
public class CustomAuthorizationFilter extends AuthorizationFilter {
#Override
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (!httpRequest.getRequestURI().startsWith(httpRequest.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
Subject subject = SecurityUtils.getSubject();
AuthenticatingSecurityManager authenticatingSecurityManager = ((AuthenticatingSecurityManager) SecurityUtils.getSecurityManager());
PrincipalCollection principals = subject.getPrincipals();
JPARealm jpaRealm = (JPARealm) authenticatingSecurityManager.getRealms().iterator().next();
AuthorizationInfo authorizationInfo = jpaRealm.getAuthorizationInfo(principals);
for (String permission : authorizationInfo.getStringPermissions()) {
if (pathsMatch(permission, request)) {
return true;
}
}
} else {
return true;
}
return false;
}
}
The pathsMatch(permission, request) method will try to validate/compare the received string permission with the path the user is trying to access.
This filter relies on ALWAYS having an authenticated user.
If the subject.getPrincipal() is null, more coding is necessary.
If anyone needs the whole code, let me know.

Liferay and ZK Integration : User Info

I wrote a portlet and added to liferay.
I have found the way to get user name from cookie:
https://www.everit.biz/web/guest/blog/-/blogs/getting-current-liferay-user-in-a-standalone-webapp?_33_redirect=/web/guest/blog
I have looked into the zk liferay package, there is just JQuery related classes.
http://www.zkoss.org/javadoc/6.0.0/zk/org/zkoss/zkplus/liferay/package-summary.html
Is there any way to get the current user in ZK?
Follow simple pattern
In the main Entry controller class, the class which extends the DHtmlLayoutPortlet
In the process method you can setup commonParameter of liferay to zk-session
I am providing you code snippet :
#Override
protected boolean process(Session sess, RenderRequest request,
RenderResponse response, String path, boolean bRichlet)
throws PortletException, IOException {
setupSessionParameters(sess, request);
return super.process(sess, request, response, path, bRichlet);
}
protected void setupSessionParameters(Session sess, RenderRequest request) {
ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
PortletSession portletSession = request.getPortletSession();
PortletPreferences prefs = request.getPreferences();
sess.setAttribute("SESSION_ID", portletSession.getId());
sess.setAttribute("THEME_DISPLAY", themeDisplay);
sess.setAttribute("GROUP_ID", themeDisplay.getScopeGroupId());
sess.setAttribute("PORTLET_PREFERENCES", prefs);
sess.setAttribute("PORTLET_ID", themeDisplay.getPortletDisplay().getId());
sess.setAttribute("currentUser", themeDisplay.getUser().getScreenName());
}
Use that zk session for getting those parameters in your application
If you want more information
Follow this link
It has all information that you want ...:)
Execution exe = Executions.getCurrent();
Session session = Sessions.getCurrent();
PortletSession ps = (PortletSession) session.getNativeSession();
User user = PortalUtil.getUser((HttpServletRequest) exe.getNativeRequest());
user.getUserId();

Resources