I am doing work on jsfunit, and i am using WebSphere6.1 application server so can anyone give me answer that is it compatible for JSFunit or i need to do some changes in my server configuration? if possible send me the example?
Thanks
Vinod
Yes,
Read JSFUnitOnWebSphere:
So to use WebSphere with JSFUnit, you
will need to create a class that
extends one of the
InitialRequestStrategy classes. See
JSFUnitTestingSecurePages for other
examples, but the following should
work for non-secure pages
public class WebSphereRequestStrategy extends org.jboss.jsfunit.framework.SimpleInitialRequestStrategy {
public Page doInitialRequest(WebClientSpec wcSpec) throws IOException {
String jsessionid = wcSpec.removeCookie("JSESSIONID");
wcSpec.addCookie("JSESSIONID", "0000" + jsessionid); // cache ID is 0000 by default
return super.doInitialRequest(wcSpec);
}
}
Then you will use this code to start
your test:
WebClientSpec wcSpec = new WebClientSpec("/index.jsf");
wcSpec.setInitialRequestStrategy(new WebSphereRequestStrategy());
JSFSession jsfSession = new JSFSession(wcSpec);
JSFClientSession client = jsfSession.getJSFClientSession();
JSFServerSession server = jsfSession.getJSFServerSession();
Related
I recently started learning liferay(7.1.2 ga3). my requirement is to change the login code(i.e write my own code for login) not look and feel in login.jsp.
I created a hook file with the following steps(in liferay developer studio) New -> Liferay Module Project -> Project Name as CustomLogin -> Build Type as Maven -> Project Template Name as war-hook -> then Finish.
After This folder was created with the name as CustomLogin and in that src -> main -> java -> CustomLogin -> I can see two Files CustomLoginLoginPostAction.java and CustomLoginStartupAction.java
in CustomLoginStartupAction.java
package CustomLogin;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.kernel.events.SimpleAction;
public class CustomLoginStartupAction extends SimpleAction {
#Override
public void run(String[] lifecycleEventIds) throws ActionException {
for (String eventId : lifecycleEventIds) {
System.out.println("Startup event ID " + eventId);
}
}
}
in CustomLoginLoginPostAction.java
package CustomLogin;
import com.liferay.portal.kernel.events.Action;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomLoginLoginPostAction extends Action
{
#Override
public void run(HttpServletRequest request, HttpServletResponse response)
{
long userId = PortalUtil.getUserId(request);
User user = UserLocalServiceUtil.fetchUser(userId);
System.out.println(user.getFirstName() + " has logged in.");
}
}
But I dont't know what to do after this. please help. or give some sample code.
Strong recommendations:
As you start learning Liferay, start with the current version, not with one from January 2019 (original 7.1.x release in 2018)
Start with OSGi plugins - they deploy a lot quicker than WAR archives and require a lot less memory at runtime
think about the requirement: You're using a platform that gives you the option to ignore all of the user management worries, and the first thing you do is to take back control of this delicate issue. Rather: Use the platform to your advantage. Consider using LDAP or SSO if you need to authenticate against another user database: That's configuration, not code - so nothing for you to maintain
That being said, the code that you posted adds to the login procedure. E.g. the LoginPostAction is executed after Liferay's own login code is already executed. This enables you to intercept a login and impose custom rules when you know what user you deal with (and that they authenticated correctly). Similarly, there's a similar LoginPreAction, that's allowing you to intercept the login process before the user's login is applied.
(A StartupAction is the wrong path - nothing to do with the login process - don't follow that path for this purpose)
What you typically do in these actions is to either deny access based on unconfigurable criteria (e.g. may the user log in from that IP? At this time?) or initialize some additional environments (e.g. triggering some backend action, initialize some information in the session). For this you can determine to do this before or after the login succeeded.
If - against my recommendation - you decide that you'll still want to customize the login process: This code for 7.0 should still work on 7.1 (and likely even on 7.4, the current version). It involves writing a custom login portlet, and the relevant code is in this class, after retrieving the HttpServletRequest (I'm omitting the presentation layer from the linked sample)
#Component(
property = {
"javax.portlet.name=MyLoginPortlet",
"mvc.command.name=/login/login"
},
service = MVCActionCommand.class
)
public class MyLoginMVCActionCommand extends BaseMVCActionCommand {
#Override
protected void doProcessAction(ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
HttpServletRequest request = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest));
HttpServletResponse response = PortalUtil.getHttpServletResponse(
actionResponse);
String login = ParamUtil.getString(actionRequest, "login");
String password = actionRequest.getParameter("password");
boolean rememberMe = ParamUtil.getBoolean(actionRequest, "rememberMe");
String authType = CompanyConstants.AUTH_TYPE_EA;
AuthenticatedSessionManagerUtil.login(
request, response, login, password, rememberMe, authType);
actionResponse.sendRedirect(themeDisplay.getPathMain());
}
}
But really: Use your time to add business value and work on business problems. Be happy that the infrastructure layer is taken care of already.
I've been working on how to save OpenIdConnecConfiguration locally in the odd case that the AuthServer is not reachable but the frontend client (e.g. Phone) still has a valid refresh token which still needs to be validated again when signing in. It is also needed to be saved locally to a file in the case that the backend (e.g. WCF) has restarted due to a update or the frequent restarts it has (once a day)
What I've done so far, I've saved the JSON object of the ".well-known/openid-configuration" to a file/variable and now I want to create the OpenIdConnectConfiguration object.
OpenIdConnectConfiguration.Create(json) does a lot of the work but the signingKeys do not get created. I think maybe it's because the authorization endpoint needs to be created in some other manner maybe?
Or maybe I'm doing this the wrong way and there is another solution to this issue. I'm working in C#.
Edit: I know there are some caveats to what I'm doing. I need to check once in awhile to see if the public key has been changed, but security wise it should be fine to save the configuration because it's already public. I only need the public key to validate/sign the jwt I get from the user and nothing more.
Figured out a solution after looking through OpenIdConnectConfiguration.cs on the official github.
When fetching the OpenIdConnectConfiguration the first time, use Write() to get a JSON string and use it to save it to file.
Afterwards when loading the file, use Create() to create the OpenIdConnectConfiguration again from the JSON string (This had the issue of not saving the signingKeys as said in the question, but alas! there is a fix)
Lastly to fix the issue with the signingKeys not being created, (this is what I found out from the github class) all we need to do is loop through the JsonWebKeySet and create them as is done in the class. We already have all the information needed from the initial load and therefore only need to create them again.
I'll leave the code example below of what I did. I still need to handle checking if he key has been changed/expired which is the next step I'll be tackling.
interface IValidationPersistence
{
void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig);
OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration();
}
class ValidationPersistence : IValidationPersistence
{
private readonly string _windowsTempPath = Path.GetTempPath();
private readonly string _fileName = "TestFileName";
private readonly string _fullFilePath;
public ValidationPersistence()
{
_fullFilePath = _windowsTempPath + _fileName;
}
public OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration()
{
FileService fileService = new FileService();
OpenIdConnectConfiguration openIdConfig = OpenIdConnectConfiguration.Create(fileService.LoadFromJSONFile<string>(_fullFilePath));
foreach (SecurityKey key in openIdConfig.JsonWebKeySet.GetSigningKeys())
{
openIdConfig.SigningKeys.Add(key);
}
return openIdConfig;
}
public void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig)
{
FileService fileService = new FileService();
fileService.WriteToJSONFile(OpenIdConnectConfiguration.Write(openIdConfig), _fullFilePath);
}
}
I'm trying to get the edit URL of a content as a string from backend, the catch is I'm inside a workflow activity, so I can't use Url.Action... or Url.ItemEditLink... or other UrlHelpers as if it were a controller or a view. Also, although I'm inside a workflow, the contents I need it for are not part of the workflowContext or the activityContext, so I can't use those or tokens either.
A solution could be to get the content metadata and the site baseUrl and try to build it manually, but I think this way is prone to errors.
Thanks.
This is how I build a Uri in an activity:
public class MyClass : Task
{
private readonly RequestContext _requestContext;
...
public MyActivity(RequestContext requestContext, ...)
{
_requestContext = requestContext;
...
}
...
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext)
{
var content = ... get using ID
var helper = new UrlHelper(_requestContext);
var baseurl = new Uri(_orchardServices.WorkContext.CurrentSite.BaseUrl);
Uri completeurl = new Uri(baseurl, helper.ItemDisplayUrl(content));
yield return T("Done");
}
}
Turns out that I actually do build the Uri semi-manually, but I haven't had issues with this method. You may be able to use just the ItemDisplayUrl for navigation inside of Orchard; I had to get the full URL because the string gets sent to an outside program (Slack).
In CRM 2011 it's easy to get current user language using javascript, using the following code:
Xrm.Page.context.getUserLcid();
Is there anyway to do the same in server side using plugins ?
Thanks and best regards
Here is a sample in a Plugin:
class GetUserLanguage : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
//PluginSetup abstracts setup code: http://nicknow.net/dynamics-crm-2011-abstracting-plugin-setup/
var p = new PluginSetup(serviceProvider);
var user = p.Context.InitiatingUserId;
var lcid = RetrieveUserUiLanguageCode(p.Service, user);
}
//From the SDK: http://msdn.microsoft.com/en-us/library/hh670609.aspx
private static int RetrieveUserUiLanguageCode(IOrganizationService service, Guid userId)
{
var userSettingsQuery = new QueryExpression("usersettings");
userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
var userSettings = service.RetrieveMultiple(userSettingsQuery);
if (userSettings.Entities.Count > 0)
{
return (int)userSettings.Entities[0]["uilanguageid"];
}
return 0;
}
}
There are a couple options for it that I've used before.
Use a Retrieve on the systemuser entity using the userid from the plugin execution context. Don't forget to set the column set to just get the user! Otherwise systemuser can be a hefty retrieve for online envs.
Issue a WhoAmI request to the server.
I personally use the former because Retrieves are very common for devs who use plugins, but not all are familiar with the WhoAmI message (it derives from retrieve: http://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.whoamirequest.aspx)
Unfortunately I have not found a way to get it without issuing a request to the server. Let me know if this helps!
Nick
I think that once the user selects a preferred locale you can pick it up using:
Thread.CurrentUICulture.LCID
basic overview...
i have a site setup in iis...
- "mysite" (wwwroot\mysite) under that there are 2 virtual directory applications
- "uploads" (\uploadfiles)
- "app" (wwwroot\myapp)
I also have a subdomain that is set up as a different site in iis...
- "beta.mysite" (wwwroot\mysitebeta) under that there are 2 virtual directory
- "uploads" (\uploadfiles)
- "app" (wwwroot\myappbeta)
the sub domain is working fine.... i can type in https://beta.mysite.com/app ... and it brings up the beta site log in perfectly fine.... the problem is, when i click on any of the buttons that create a post back... it reverts to https://www.mysite.com/app...
all of the links display the correct relative path to their files.... and if i type in https://beta.mysite.com/app/dir/page.aspx... it will actually go to that page on the beta site, all the links are going to the right spots... its just the postbacks that are killing me...
Have you tried setting a different application pool for these two websites? Looks like it's trying to be "smart" and concludes that the two virtual directories are actually the same website.
If all else fails, you could rewrite the postback URL in the FORM-tag that ASP.NET generates manually. Using an App_Browsers file and a ControlAdapter are probably the cleanest way of doing that.
I have an example of such a ControlAdapter implementation, though it is intended to work with URL rewriting to prevent reverting to the actual behind-the-scenes URL on postback. However, I think it would work for your problem out-of-the-box
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}
}
public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
private const string contextItemKey = "FormActionWritten";
public RewriteFormHtmlTextWriter(HtmlTextWriter writer) : base(writer)
{
InnerWriter = writer.InnerWriter;
}
public RewriteFormHtmlTextWriter(System.IO.TextWriter writer) : base(writer)
{
base.InnerWriter = writer;
}
public override void WriteAttribute(string name, string value, bool fEncode)
{
// If the attribute we are writing is the "action" attribute, and we are not on a sub-control,
// then replace the value to write with the raw URL of the request - which ensures that we'll
// preserve the PathInfo value on postback scenarios
if (name == "action" && !HttpContext.Current.Items.Contains(contextItemKey))
{
// Use the Request.RawUrl property to retrieve the un-rewritten URL
value = HttpContext.Current.Request.RawUrl;
HttpContext.Current.Items[contextItemKey] = true;
}
base.WriteAttribute(name, value, fEncode);
}
}
Form.browser file:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormRewriterControlAdapter" />
</controlAdapters>
</browser>
</browsers>