Marius Popa
Marius Popa

Reputation: 584

Apache Tapestry user logged in feature

I am trying to create a login feature for my apache tapestry website, where after logging in, instead of the 'Log In' and 'Register' button, the email of the logged user should be displayed, along with a 'Log Out' button.

Could anyone please tell how should this be implemented the best way?

I can't seem to figure out how should i detect if the user is logged in, in the frontend part, in order to display a different menu options (i am new in tapestry).

Best regards, Marius.

Upvotes: 0

Views: 943

Answers (2)

Marius Popa
Marius Popa

Reputation: 584

After a little bit of research regarding this matter, i found the following approach:

1) I created an Authenticator interface

public interface Authenticator {

Users getLoggedUser();
boolean isLoggedIn();
void login(String email, String password) throws AuthenticationException;
void logout();
}

2) Also created an AuthenticatorImpl.java class that implements that interface

public class AuthenticatorImpl implements Authenticator {

public static final String AUTH_TOKEN = "authToken";

@Inject
private StartDAO dao;

@Inject
private Request request;

public void login(String email, String password) throws AuthenticationException
{

    Users user = dao.findUniqueWithNamedQuery("from Users u where u.Email = '" + email + "' and u.Password = '" + password + "'");

    if (user == null) { throw new AuthenticationException("The user doesn't exist"); }

    request.getSession(true).setAttribute(AUTH_TOKEN, user);
}

public boolean isLoggedIn()
{
    Session session = request.getSession(false);
    if (session != null) { return session.getAttribute(AUTH_TOKEN) != null; }
    return false;
}

public void logout()
{
    Session session = request.getSession(false);
    if (session != null)
    {
        session.setAttribute(AUTH_TOKEN, null);
        session.invalidate();
    }
}

public Users getLoggedUser()
{
    Users user = null;

    if (isLoggedIn())
    {
        user = (Users) request.getSession(true).getAttribute(AUTH_TOKEN);
    }
    return user;
}
}

3) Created the corresponding binding in the AppModule.java class

public static void bind(ServiceBinder binder)
{
    binder.bind(StartDAO.class, StartDAOImpl.class);
    binder.bind(Authenticator.class, AuthenticatorImpl.class);
}

4) And on my Layout.java page i used it in the following way

@Property
private Users user;

@Inject
private Authenticator authenticator;

void setupRender()
{
    if(authenticator.getLoggedUser().getAccountType().equals("Administrator")){
        administrator = authenticator.getLoggedUser();
    }

    user = authenticator.getLoggedUser();

}

Object onLogout(){
    authenticator.logout();
    return Login.class;
}

Layout.tml

<t:if test="user">
        <span class="navbar-right btn navbar-btn" style="color: white;">
            Welcome ${user.Name}! <a t:type="eventLink" t:event="Logout" href="#">(Logout)</a>
        </span>
    </t:if>
    <t:if negate="true" test="user">
        <span class="navbar-right">
                <t:pagelink page="user/create" class="btn btn-default navbar-btn">Register</t:pagelink>
                <t:pagelink page="user/login" class="btn btn-default navbar-btn">Sign in</t:pagelink>
        </span>
    </t:if>

This worked for me without any problems. Hope that it helps others.

Best regards, Marius.

Upvotes: 0

Howard M. Lewis Ship
Howard M. Lewis Ship

Reputation: 549

Authentication (of which login is a part) is very application specific. How you define a User (or do you call it a "Customer", for example) is not something the framework does.

Typically, you will have a SessionStateObject representing your User. You can then use something like this in your layout:

<t:if test="user">
  <t:logoutLink/>
  <p:else>
     <t:signInForm/>
</t:if>

Again, components LogoutLink and SignInForm are for you to implement.

The user may be exposed from the Java code as:

@Property @sessionState(create=false) private User user;

This says that the user field is linked to a value stored in the HTTP session; further, the User will not be created when the field is first read; instead, your SignInForm component should assign to its user field.

Upvotes: 2

Related Questions