We have a requirement wherein I need to force logout user if some condition is met. I have written a PostLoginAction hook to check the condition and doing getSession().invalidate() when the condition is met. But after this, since there is no active session, Liferay takes me to login screen by default(prolly using a filter). If I try to redirect to one of the error pages inside /ROOT/html/common/, i get a cryptic internal server error page.
At this point, I need to display an error message but all the redirects are ending up on login page. What should be the right way of doing this?
Just on a side note, is there a way to display the error message on the login page itself instead of redirecting to some other page? I have tried using sessionErrors.add() method to achieve the same, but that too has not worked.
Let me know if you need any more details.
Please follow the below steps for achieving this
Create a post login event hook plugin
Create portal.properties with given props
login.events.post=com.liferay.sample.hook.LoginActionRedirect
Create entry in liferay-hook.xml
portal.properties
Create class LoginActionRedirect
package com.liferay.sample.hook;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.liferay.portal.kernel.events.Action;
import com.liferay.portal.kernel.events.ActionException;
public class LoginActionRedirect extends Action {
#Override
public void run(HttpServletRequest req, HttpServletResponse res)
throws ActionException {
System.out.println("Invalidating user");
req.getSession().invalidate();
try {
//Use page URL to be redirected
res.sendRedirect(req.getContextPath()+"/web/guest/WCM");
} catch (IOException e) {
System.out.println("Something went wrong while performing IO operations");
}
}
}
Add the following property to portal-ext.properties file,to avoid redirection with locale prepended
locale.prepend.friendly.url.style=0
Related
I have implented GetAllBusinessPartnerCommand and also customized the code in the BusinessPartnerServlet. When I try to call the application with the customized code, I always get this error.
Code GetAllBusinessPartnersCommand
package com.sap.cloud.s4hana.examples.commands;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import com.sap.cloud.s4hana.examples.BusinessPartnerServlet;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.frameworks.hystrix.HystrixUtil;
import com.sap.cloud.sdk.s4hana.connectivity.ErpCommand;
import com.sap.cloud.sdk.s4hana.datamodel.odata.helper.Order;
import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartner;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;
public class GetAllBusinessPartnersCommand extends ErpCommand<List<BusinessPartner>>{
private static final Logger logger = CloudLoggerFactory.getLogger(BusinessPartnerServlet.class);
public static final String CATEGORY_PERSON ="1";
public GetAllBusinessPartnersCommand() {
super(HystrixUtil.getDefaultErpCommandSetter(
GetAllBusinessPartnersCommand.class,
HystrixUtil.getDefaultErpCommandProperties().withExecutionTimeoutInMilliseconds(10000)));
}
#Override
protected List<BusinessPartner> run() throws Exception {
// TODO Auto-generated method stub
return new DefaultBusinessPartnerService().getAllBusinessPartner()
.select(BusinessPartner.BUSINESS_PARTNER,
BusinessPartner.LAST_NAME,
BusinessPartner.FIRST_NAME,
BusinessPartner.IS_MALE,
BusinessPartner.IS_FEMALE,
BusinessPartner.CREATION_DATE)
.filter(BusinessPartner.BUSINESS_PARTNER_CATEGORY.eq(CATEGORY_PERSON))
.orderBy(BusinessPartner.LAST_NAME, Order.ASC)
.execute();
}
#Override
protected List<BusinessPartner> getFallback() {
logger.warn("Fallback called because of exception:",
getExecutionException());
return Collections.emptyList();
}
}
n the following you can see the commands and the offered workaround for the problem set ALLOW_MOCKED_AUTH_HEADER=true. Before testing I checked if all variables are set correctly and set ALLOW_MOCKED_AUTH_HEADER=true again because I set it too early before.
After this steps i build my project like i always do and get the error from above when im calling the service. I also read this post where someone have the same problem and used the mentioned workaround. But this doesnt work for me and i have no clue why. TenantNotAvailableException, when trying to call business partner from s4 CF SDK
error when call page
Starting mock-server
set variables and workaround plus check
Unfortunately SAP Cloud SDK 2.x is no longer supported. Please use our migration guide to move to the latest version 3.43.0 You can find my blog post on this topic too. If you face any issues, please create another StackOverflow question (with tag sap-cloud-sdk) or comment to the blog post. For more details, please find our documentation.
Maybe this is more of an ASP.NET MVC question than an Orchard question but I'm relatively new to both and I don't know the answer in either case.
ASP.NET MVC applications don't technically have a single point of entry, so where am I supposed to put code that I want to always run each and every time someone visits any page, regardless of layer or origin or permissions? Is there a specific Orchard way of doing this?
If it makes a difference, what I'm specifically trying to do at the moment is to restrict the IP range that has access to my website. I want to look at every incoming request and check if the user is either authenticated or has an IP in the allowed range that I configured in my custom settings.
I can think of some quick and dirty ways to achieve this like putting the check in Layout and wrap a condition around all of my zones or implement IThemeSelector to switch to a different Theme but I'd like to do it properly.
All what should you do to achieve this, is implementing new IActionFilter or IAuthorizationFilter like the following:
public class CheckAccessFilter : FilterProvider, IActionFilter, IAuthorizationFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
// here you can check the incoming request, and how the system will deal with it,
// before executing the action
}
public void OnActionExecuted(ActionExecutedContext filterContext) {
}
public void OnAuthorization(AuthorizationContext filterContext) {
// here you can authorize any request
}
}
But if you want only to authorize based on content items (like: Widgets, Pages, Projections), you can implement IAuthorizationServiceEventHandler:
public class IPAuthorizationEventHandler : IAuthorizationServiceEventHandler {
public void Checking(CheckAccessContext context) {
}
public void Adjust(CheckAccessContext context) {
}
public void Complete(CheckAccessContext context) {
}
}
The best sample you can follow to implement this approach is SecurableContentItemsAuthorizationEventHandler, you can find it in Orchard.ContentPermissions module.
I've created the check-in policy from this MSDN article as an example (code is just copy / pasted).
This works fine, it appears when I try and do a check-in, however it appears as an warning. So I can ignore it by just pressing Check In again. How can I change the code, as listed in the URL, so that it will return an Error not a warning. I can't see any properties on PolicyFailure to do this.
Essentially I want it to look like the error in this screenshot:
Image Source
EDIT: Here is the exact code that I'm using. Now it is slightly modified from the original source, but not in any massive way I wouldn't have thought. Unfortunately I can't post screenshots, but I'll try and describe everything I've done.
So I have a DLL from the code below, I've added it into a folder at C:\TFS\CheckInComments.dll. I added a registry key under Checkin Policies with the path to the DLL, the string value name is the same as my DLL (minus .dll). In my project settings under source control I've added this Check-In Policy.
It all seems to work fine, if I try and do a check-in it will display a warning saying "Please provide some comments about your check-in" which is what I expect, what I'd like is for it to stop the check-in if any policies are not met, however I would still like the user to be able to select Override if necessary. At the moment, even though there is a warning, if I was to click the Check In button then it would successfully check-in the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace CheckInComments
{
[Serializable]
public class CheckInComments : PolicyBase
{
public override string Description
{
get
{
return "Remind users to add meaningful comments to their checkins";
}
}
public override string InstallationInstructions
{
get { return "To install this policy, read InstallInstructions.txt"; }
}
public override string Type
{
get { return "Check for Comments Policy"; }
}
public override string TypeDescription
{
get
{
return "This policy will prompt the user to decide whether or not they should be allowed to check in";
}
}
public override bool Edit(IPolicyEditArgs args)
{
return true;
}
public override PolicyFailure[] Evaluate()
{
string proposedComment = PendingCheckin.PendingChanges.Comment;
if (String.IsNullOrEmpty(proposedComment))
{
PolicyFailure failure = new PolicyFailure("Please provide some comments about your check-in", this);
failure.Activate();
return new PolicyFailure[1]
{
failure
};
}
else
{
return new PolicyFailure[0];
}
}
public override void Activate(PolicyFailure failure)
{
MessageBox.Show("Please provide comments for your check-in.", "How to fix your policy failure");
}
public override void DisplayHelp(PolicyFailure failure)
{
MessageBox.Show("This policy helps you to remember to add comments to your check-ins", "Prompt Policy Help");
}
}
}
A check-in policy will always return a warning and if your user has permission to ignore them, then they can.
Users can always override the policy. You can query the TFS warehouse to generate a report of users violating the policies and their reasons for the violation if they provided any. Or setup an alert whenever someone ignores these polite warnings.
There is no way to enforce this from the policy itself. Only from a server side plugin, as described by Neno in the post you quoted. Such a server side plugin can be created for 2012 or 2010 as well. The process is explained here.
I just got past that issue by turning on Code Analysis on my project - right click on your project, click properties, go to Code Analysis, select the Configuration drop down and pick "All Configurations", select the "Enable Code Analysis on Build".
Do a build and make sure you have no errors / warnings.
This will get you past any policies requiring code analysis on build.
I have a button on an XPage where I want to connect to a remote OpenOffice instance. OpenOffice is started and is listening for a socket connection.
The onclick event of the button runs following SSJS:
oo = new com.test.OpenOffice();
oo.init("host=127.0.0.1,port=8107");
oo.openFile("C:\\TEMP\\Test.odt");
The code raises an excepction jva.lang.IlleagalStateException: NotesContext not initialized for the thread
The exception is raised within the method initof the class OpenOffice.
The relevant parts of the class OpenOffice is the following code:
public class DHOpenOffice implements Serializable {
private static final long serialVersionUID = -7443191805456329135L;
private XComponentContext xRemoteContext;
private XMultiComponentFactory xMCF;
private XTextDocument oTextDocument;
public DHOpenOffice() {
xRemoteContext = null;
xMCF = null;
oTextDocument = null;
}
public void init(String hostAdr) throws java.lang.Exception {
xRemoteContext = null;
XComponentContext xLocalContext = Bootstrap.createInitialComponentContext(null);
XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext);
String sConnect = "uno:socket," + hostAdr + ",tcpNoDelay=0;urp;StarOffice.ServiceManager";
Object context = xUrlResolver.resolve(sConnect);
xRemoteContext = UnoRuntime.queryInterface(XComponentContext.class, context);
xMCF = xRemoteContext.getServiceManager();
}
The code line Object context = xUrlResolver.resolve(sConnect); is the one that raises the exception.
Why is this happing? What is the reason for this exception and how can I resolve the situation?
N.B.: The class code runs smoothly in a standalone application. The error occurs only when the code is started by a SSJS code.
It looks like a threading issue. There are a number of things you can go and try:
Wrap the whole interaction into a custom class and use it from a managed bean instead of calling it from SSJS
Make sure not to hand over any Notes objects into the custom class, only your own
Check if the Open Document Toolkit would be sufficient to do the operations you are interested in, so you don't need to run OO
let us know how it goes
Update
Try to get outside the standard XPages cycle. One way is to deploy a custom plug-in servlet:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class OpenOfficeServlet extends HttpServlet {
// Your code goes here
}
You need to get the plugin.xml right:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension point="org.eclipse.equinox.http.registry.servlets">
<servlet alias="/ooproxy" class="com.yourcompany.OpenOfficeServlet" />
</extension>
</plugin>
Then you could e.g. post a JSON structure or a serializable Java object to the servlet with the data and process it there (async if necessary). You deploy such a plug-in using the updatesite.nsf
Thanks to the answer of #stwissel I was able to solve the problem (he pointed me to the right direction).
I could solve the problem with a simple OSGI plug-in. The servlet approach solved the problem, too, but for me the OSGI plug-in was easier to use.
So these are the steps to create the plug-in
start a new plugin project
copy the open office jar files into the project and include them into the build path
copy the custom class that uses the UNO API into the plug-in
create a feature project for the plugin
create an update site
deploy the plugin via an update site
The following site where also quite helpfull:
Creating an XPages Library
Wrap an existing JAR file into a plug-in
I finally got my test servlet working from this thread?
Calling HttpServlet class from xpages client side script and regular notes forms?
The issue that remains is I am being asked to login. But my final servlet will need to run without logging in. I have my acl set to Read public document and Write public documents for anonymous.
What I don't know how to do is to make the serlet public access. Other design documents have an "Available to Public Access users" property but I am seeing no such property for java files. Would this be set somewhere else? Maybe in my IServletFactory perhaps?
I don't know why I was required to log in before but it looks like it is now working. The only thing that is requred is that Read Public Public Document be enabled.
This is a bit concerning since it at least appears there is no way to make some servlets non-public. In my case it won't be an issue but it could be an issue for others.
Also what I noticed is that if you change the Public Access acl setting, it looks like you need to rebuild your servlets for some reason or the servlets won't run. When I get a chance I will open a ticket with notes support for both of these issues.
For those wanting to execute a servlet, I suggest this article:
http://8b30b0.wordpress.com/2013/02/04/creating-a-basic-domino-servlet/#comments
But here is a much more simplifed version of IServletFactory that might be easier to understand and get working.
package test;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import com.ibm.designer.runtime.domino.adapter.ComponentModule;
import com.ibm.designer.runtime.domino.adapter.IServletFactory;
import com.ibm.designer.runtime.domino.adapter.ServletMatch;
public class TestFactory implements IServletFactory {
private ComponentModule module;
public ServletMatch getServletMatch(String contextPath, String path)
throws ServletException {
System.out.println("TestFactory:getServletMatch");
String servletPath = "";
String pathInfo = path;
return new ServletMatch(getWidgetServlet(),servletPath,pathInfo);
}
public void init(ComponentModule arg0) {
System.out.println("TestFactory:init");
this.module = arg0;
}
public Servlet getWidgetServlet() throws ServletException {
return module.createServlet("com.pnc.cld.HelloWorld", "testServlet",null);
}
}