How to submit a valid user request to Liferay Default Landing Page - liferay

I am using Liferay 6 .
I have created a page and added 6 portlets to it and configured inside portal-ext.properties file as
auth.forward.by.last.path=true
default.landing.page.path=/user/test/home
This private page with all my 6 portlets is shown only when i use Liferay's sign in Portlet (The default login page of Liferay )
Similarly i have my Custom Portlet made of struts2 , which is shown on entering http:localhost:8086 as shown below
<s:form action="helloForm" method="POST" theme="simple">
Enter Your Name:<s:textfield name="namer" />
Enter Your Name:<s:textfield name="passer" />
<s:submit/>
</s:form>
Currently , when user clicks on submit the Struts2 Action class recivies that as shown
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
String name = ParamUtil.getString(request, "namer");
// does Database check and decides the return page
return ActionSupport.SUCCESS;
}
Now my requirement is that , if he is a valid user , i want to redirect him/her to the Landing Page configured
Please tell me how to do this ??

HttpServletResponse response = ServletActionContext.getResponse();
String targetUrl = "/user/test/home";
response.sendRedirect(targetUrl);

Related

How to preserve ReturnUrl query parameter when submiting form

I'm using cookie based authentication with Razor Pages.
When the user does not have an authentication cookie in the browser and tries to access a razor page with, for exmaple, https://localhost:8080/admin/protected
by default the aspnet core framework redirects to the LoginPath specified in CookieAuthenticationOptions. If that Url is something like /login, then the browser is redirected automatically to /login?ReturnUrl=%2Fadmin%2Fprotected
That's perfect. The problem is that I don't know how this is supposed to work later, because if my /login razor page submits a form (for example it posts the username and password), the ReturnUrl parameter is lost.
What's the "right" way to preserve this? I'm trying to find something in the documentation without success, nor I can find any asp tag helper.
PS: I was following this as a guide: https://www.mikesdotnetting.com/article/335/simple-authentication-in-razor-pages-without-a-database
I implemented a workaround, although it looks "hacky" and I was expecting to have some syntatic sugar from the Razor pages to preserve this ReturnUrl.
In any case, the solution is to include in my form model a field where I will store the ReturnUrl query parameter when the page renders (e.g: Get request). For example:
public class LoginForm
{
public string ReturnUrl { get; set; } = string.Empty;
}
and in my razor page code:
public async Task OnGetAsync()
{
var nameValueCollection = HttpUtility.ParseQueryString(Request.QueryString.Value);
const string returnUrlKey = "returnUrl";
var returnUrl = nameValueCollection.Get(returnUrlKey);
LoginForm.ReturnUrl = returnUrl; //here I save the value on the form
// do other things
}
Now in my razor page I add a hidden field to pass that value back to the server when posting the form. For example:
<form method="post">
<input asp-for="LoginForm.ReturnUrl" type="hidden" />
<button type="submit" asp-page-handler="Login">Login</button>
</form>
And then I can access the original value in
public async Task<IActionResult> OnPostLoginAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
return Redirect(LoginForm.ReturnUrl);
}
Notice that the ReturnUrl value is preserved even if there is a validation error and the ModelState is invalid, which is what I want.

Edit a specific User attribute in a page in Concrete5

My concrete 5.6.3.1 site has public registration. I have attribute called "I am a ambassador", which is a checkbox that shows in registration and in your profile.
My question is i need this particular attribute to be shown and can be edited inside a specific page.
For Eg: I have a page called Sing up as Ambassador, when going to this page i need to show this particular check box which the user can enable/disable it and save it.(same as profile edit). Anybody there to help me?
NOTICE: This answer is for legacy concrete5 version 6, only some of it will apply for version 7
So for this question, there are a few parts that we'll need to go over.
How do I determine the current logged in user?
$user = new User();
$user_info = UserInfo::getByID($user->getUserID());
How do I get an attribute value?
$user_info->getAttribute('my_attribute_handle');
How do I set an attribute value?
$user_info->setAttribute('my_attribute_handle', $value);
So then in my singlepage view method, I'll have something like:
public function view()
{
$user = new User();
$some_attribute = false;
if ($user->isLoggedIn()) {
$user_info = UserInfo::getByID($user->getUserID());
$some_attribute = $user_info->getAttribute('some_attribute');
}
$this->set('some_attribute', $some_attribute);
}
And then in my singlepage view file, I have:
<input type='checkbox' value='1' name='some_attribute' <?= $some_attribute ? 'checked' : '' ?> />
Where ever my form ends up submitting, I'll do this:
$user = new User();
if ($user->isLoggedIn()) {
$user_info = UserInfo::getByID($user->getUserID());
$user_info->setAttribute('some_attribute', $_REQUEST['some_attribute'] == 1);
}

Navigate after successfull action on commandButton

I am building a JSF application using Primefaces mobile (0.9.3 with Primefaces 3.5).
I hava a login page, on this login page there is a login button defined as followed:
<p:commandButton value="#{msg['label.login']}" action="#{loginBean.login}" update="usernameMsg" />
The loginBean.login method is defined as followed:
public String login() {
try {
//do login
return "#loggedInTarget?transition=fade";
} catch (UserNotValidException e) {
//User not valid, display exception
FacesContext
.getCurrentInstance()
.addMessage(
"loginForm:username",
new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"",
messageService
.getMessage("error.message.loginNotSuccessfull")));
}
return null;
}
In my main xhtml (the same in which the button is defined), I have defined the following addtional views:
<pm:view id="registerTarget">
<ui:include
src="/WEB-INF/c52bc19d58a64ae4bd12dec187a2d4b7/register.xhtml" />
</pm:view>
<pm:view id="loggedInTarget">
TEST
</pm:view>
I do it that way because I want to use transitions within Primefaces mobile. To get to the register page I use a p:button which works fine:
<p:button value="#{msg['label.register']}"
href="#registerTarget?transition=fade" />
Why is my login button not working? I also tried to put in "#loggedInTarget?transition=fade" directly as action, but this didn't work either :(
I need the action, because I have to check if the user credentials are valid. If they are valid I want to display my loggedInTarget.
How can I achieve it?
Thanks in advance!
EDIT:
The button is inside a form.
The navigation case outcome value must represent a view ID, not an URL (for sure not a hash fragment). Try with <p:button outcome="...">, and you'll see that it fails over there as well.
Your closest bet is sending a redirect.
public void login() throws IOException {
// ...
externalContext.redirect("#loggedInTarget?transition=fade");
// ...
}
This is also exactly what the <p:button href="..."> does under the covers: causing a GET request on the given URL.

h:commandButton action redirect to context root, possible?

Project context
I've created from scratch an URL rewriting with two major component :
public class URLFilter implements Filter
{
...
}
public class URLViewHandler extends GlobalResourcesViewHandler
{
...
}
The first class is used to forward clean URLs to the right view with an ID different for each page. The second class override the function getActionURL() so that h:form and ajax functionnalities continues to work.
Theses classes translate like this :
Real URL Internal URL
/ <-> page.jspx?key=1
/contact <-> page.jspx?key=2
/projects/management <-> page.jspx?key=3
etc
Current solution
My problem right now is for my user login and logout button :
<!-- Login button used if user is not logged, go to a secured page (which display error message). If he log with this button, the current page is reloaded and displayed properly. This button works perfectly -->
<h:commandButton rendered="#{pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" />
<!-- Login button used anywhere on public pages that redirect to user home after login, works perfectly since I haven't changed to clear url. -->
<h:commandButton rendered="#{not pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" action="userHome.jspx?faces-redirect=true" />
<!-- Logout button that works (it redirects at http://website.com/context-name/ but keep the ?key=1 at the end. -->
<h:commandButton value="#{msg.button_disconnect}" actionListener="#{userActions.onButtonLogoutClick}" action="page.jspx?key=1&faces-redirect=true" styleClass="button" style="margin-left: 5px;" />
My whishes
My question : Is there a better way to program the logout button since I need to redirect to context-root, currently I'm using the view name with the home page key but I would prefer 1. using a real path 2. not keep the ?key=1 at the url.
Thank you!
Final code
Based on BalusC answer, here is my final code to share to others :
#ManagedBean
#RequestScoped
public class NavigationActions
{
public void redirectTo(String p_sPath) throws IOException
{
ExternalContext oContext = FacesContext.getCurrentInstance().getExternalContext();
oContext.redirect(oContext.getRequestContextPath() + p_sPath);
}
}
<h:commandButton rendered="#{not pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" action="#{navigationActions.redirectTo(userSession.language.code eq 'fr' ? '/profil/accueil' : '/profile/home')}" />
Since I don't need the key when I have the path, it is even more better, thank you again BalusC to put me on the right track! Sent a small donation :)
This isn't possible with (implicit) navigation. The / is unfortunately not a valid JSF view ID.
Use ExternalContext#redirect() instead. Replace
action="page.jspx?key=1&faces-redirect=true"
by
action="#{userActions.redirectToRootWithKey(1)}"
with
public void redirectToRootWithKey(int key) throws IOException {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "?key=" + key);
}

Liferay - Link in Dockbar depedent on user group using hook

I am fairly new to the new liferay platform and using hooks. I am adding the currently logged-in user's email next to their name in the Dockbar portlet. I would like this email to link to, when clicked, to a different link depending on whether the user is in either of two groups.
This is what I have written so far in the hook...
//if user is in "group1" show this link
<aui:a cssClass='<%= "user-email" %>' href="link1" title="Gmail">
<%= "(" + HtmlUtil.escape(user.getDisplayEmailAddress() + ")") %>
</aui:a>
//if user is in "group2" show this link
<aui:a cssClass='<%= "user-email" %>' href="link2" title="Outlook">
<%= "(" + HtmlUtil.escape(user.getDisplayEmailAddress() + ")") %>
</aui:a>
How can I achieve this should I be using a <c:if> tag? or can someone exemplify?
You can retrieve the scopeGroupId available in the dockbar's jsp and from that you can retrieve the Group instance.
And then check on which group's page the User is currently and change the href accordingly.
or you can also use the following code in your JSP:
Group group = null;
if(themeDisplay.getLayout().getGroup().isSite()) { // this will tell if the Group is a site or not
group = themeDisplay.getLayout().getGroup(); // fetching the site group instance
}
String href;
if (themeDisplay.getLayout().getGroup().getName().equalsIgnoreCase("group1")) {
href = "group1_link";
} else {
href = "group2_link";
}
Note: themeDisplay is available in Liferay's JSP and to use in your custom portlets you can use <liferay-theme:defineObjects /> tag.
Hope I have understood your question properly and answered accordingly.

Resources