Strategy when retrieving user name from session - java

I have a technical problem and I am not sure about the correct way to solve:
In a web page I am developing, I have to store the current user name from session (the person who is logged in) to "stamp" an action. (For instance, "The user created this file on "). My algorithm retrieves the user name from session but it obviously changes for each user. Therefore, the is always been the one of the user logged in, and not the creator name.
Any hint anyone?
Thanks!

So logically these are the steps you want?
User1 logs in
User1's name gets stored in Http session
User1 creates File42
System stores in database that User1 created File42 on Timestamp257
User1 logs out
User 2 logs in
User2's name gets stored in Http session
User2 views information about File42
System reads from database that User1 created File42 on Timestamp257
System displays information to User2
I think you might be missing the part where the system stores stuff (e.g. in a database).
EDIT: If you don't need persistence you could store shared data in the ServletContext. Note this is not a serious solution but could be used for a quick prototype or demo. Don't even think about doing this in production, it's got issues.
In your servlet do:
private static Map<String, FileData> fileAccess;
private class FileData {
String userName;
Date timeStamp = new Date();;
String fileName;
FileData(String userName, String fileName) {
this.userName = userName;
this.fileName= fileName;
}
}
public void init(ServletConfig config) {
String attributeKey = "fileAccess";
fileAccess = config.getServletContext().getAttribute(attributeKey);
if (fileAccess == null) {
fileAccess = new HashMap<String, FileData>();
config.getServletContext().setAttribute(attributeKey, fileAccess);
}
}
// in this example a POST means a user accesses a file
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
// get the user name from the current session
String userName = req.getSession().getAttribute("userName");
// get the file name from the request (posted from the file access form)
String fileName = req.getParameter("fileName");
// check if we have the necessary data
if (userName == null || fileName == null) {
resp.getWriter().write("Invalid file access request");
resp.getWriter().flush();
return;
}
// create and fill file data wrapper
FileData fileData = new FileData(userName, fileName);
// store the file data in the shared fileAccess map.
// synchronized to block simultaneous acccess from different threads
synchronized (fileAccess) {
// note: any previously stored FileData object gets replaced
fileAccess.put(fileName, fileData);
}
// display the result to the user
display(fileData, resp);
}
// in this example a GET means a user views a file
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
// get the file name parameter from the request (sent as part of the view-file request)
String fileName = req.getParameter("fileName");
// check if we have the necessary data
if (fileName == null) {
resp.getWriter().write("Invalid view file request.");
resp.getWriter().flush();
return;
}
// get the file data from the shared fileAccess map.
// synchronized to block simultaneous acccess from different threads
synchronized (fileAccess) {
FileData fileData = fileAccess.get(fileName);
// display the result to the user
display(fileData, resp);
}
}
private void display(FileData fileData, HttpServletResponse resp) {
resp.getWriter().write("File accessed:");
resp.getWriter().write("User: " + fileData.userName);
resp.getWriter().write("File: " + fileData.fileName);
resp.getWriter().write("Timestamp: " + fileData.timeStamp);
resp.getWriter().flush();
}

Related

retrieve last id inserted in object in a servlet

im doing an assessment for my college, my teacher gave me some initial code to copy and now im stucked with my own code. Basically this code create a new object to insert in the DB with an id. i need to catch the transaction id created in the object to send it to the next page. to review the transaction (marketplace portal). sorry for my english but its a little bit hard.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
int user_id = Integer.parseInt(request.getParameter("user_id"));
int feed_id = Integer.parseInt(request.getParameter("feed_id"));
Date now = new java.sql.Date(System.currentTimeMillis());
//int transaction_done =0; MEANS NO TRANSACTION
//int transaction_done =1; MEANS USER NTERESTED SEND APPLICATION TO REACH FEEDER
//int transaction_done =2; MEANS FEEDER DECLINE TRANSACTION
//int transaction_done =3; MEANS TRANSACTION SUCCESSFULL, PROCEED WITH REVIEW
int transaction_done =1;
TransactionService objTransactionService = new TransactionService();
Transaction objTransaction = new Transaction(0, feed_id,user_id,now,transaction_done);
if (objTransactionService.saveTransaction(objTransaction)) {
HttpSession sesion=request.getSession();
String done = "transaction in process! well done.";
sesion.setAttribute("done", done);
response.sendRedirect("chat.jsp?done=true");
} else {
HttpSession sesion=request.getSession();
String done = "Error, try again.";
sesion.setAttribute("done", done);
response.sendRedirect("chat.jsp?done=false");
}
}
hope you can help me.

Adding attributes to Wicket session

There is an implementation of WebSession, which supposed to store ID of logged user:
public class SecurityWebSession extends AuthenticatedWebSession {
public SecurityWebSession(Request request) {
super(request);
bind();
}
...
#Override
public boolean authenticate(String username, String password) {
user = usersFacadeLocal.findByEmail(username);
if (user != null) {
try {
boolean valid = PasswordHash.validatePassword(password, user.getPassword());
if (valid) {
WebSession.get().setAttribute(USER_ID, user.getId());
}
return valid;
} catch (Exception ex) {
logger.error("Authenticate ERROR", ex);
}
}
return false;
}
}
However, when I access SecurityWebSession to get ID of logged user from WebPage class, it returns null. I came across that Session does not store values which were added from its body. But it perfectly stores values if set them from classes inherited from Wicket's WebPage.
I did not find any mention in documentation about this situation. How can I add to Session attributes from Session?
Do you use Wicket 6.19.0 by chance?
If this is the case then you hit https://issues.apache.org/jira/browse/WICKET-5845. It is fixed in 6.20.0.
If this is not the case then please create a new ticket with a quickstart application showing the problem. Thanks!
I guess the problem lies within AuthenticatedWebSession.signIn(final String username, final String password).
This one calls your authenticate method and will destroy() and bind() your session again (this is done to avoid Session fixation).
You can however temporarily store the values you need by overriding replaceSession():
// this will be called *after* a successful authenticate
#Override
public void replaceSession() {
//temp store any values you want to carry over to the new session...
super.replaceSession();
//reset them to the session after super.replaceSession();
}

How to retrieve data from the Google Datastore?

I use java servlets. I wrote a code which has no error,But it returns me an empty list always.
I dint want to update Datastore from the servlet. i just want to read entities. i'll enclose my code tell me where is the problem.
I always get the data store is empty.This is just a test code.Even this dosent seem to work. searched internet for week . All for vain.
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
resp.getWriter().println(datastoreService.getIndexes());
if (datastoreService.getIndexes().isEmpty())
resp.getWriter().println("the data store is empty");
Query query = new Query("IMAGES");
PreparedQuery pq = datastoreService.prepare(query);
for (Entity entity :pq.asIterable())
{
resp.getWriter().println(entity.getKind() );
resp.getWriter().println(entity.getAppId() );
resp.getWriter().println(entity.getKey() );
}
if (!pq.asIterable().iterator().hasNext())
resp.getWriter().println("the data store is empty");
}
I rectified my problem . I forgot to add a namespace. here is a snippet on How to set namespace in GAE DataStore.
// Set the namepace temporarily to "abc"
String oldNamespace = NamespaceManager.get();
NamespaceManager.set("abc");
try {
... perform operation using current namespace ...
} finally {
NamespaceManager.set(oldNamespace);
}

Set data into ActionResponse Portlet GateIn

I am working on portlet for GateIn 3.6. Currently i have created a page that list the records in table. When user click on any row then it takes to description page.
Right now when user click on row it loads the details page but values are not available. What i am doing details are here..
#RenderMode(name = "view")
public void display(RenderRequest request, RenderResponse response) throws PortletException, IOException, NamingException {
RecordsDAO recordsDAO = new RecordsDAOImpl();
// Records listing available on listing page
request.setAttribute("recordsList", recordsDAO.getAllRecords());
// tried to load record detail page when user click one row
if(actionJsp == null || actionJsp.equals("")){
getPortletContext().getRequestDispatcher("/jsp/ListRecords.jsp").
include(request, response);
} else {
getPortletContext().getRequestDispatcher("/jsp/DetailsBoxRecord.jsp").
include(request, response);
}
actionJsp = "";
}
and the process action is
#ProcessAction(name = "details")
public void details(ActionRequest request, ActionResponse response) throws PortletException, IOException {
RecordsDAO recordsDAO = new RecordsDAOImpl();
int id = Integer.parseInt(request.getParameter("id"));
RecordsForm recordsForm = recordsDAO.getRecord(id);
// way 1 set request attribute
request.setAttribute("details", recordsForm);
// way 2 set response attribute -- display error that cannot set Form type values
response.setRenderParameter("details", recordsForm);
actionJsp = "values";
}
Option1:
I have tried to set RecordsForm type values in request.setAttribute, its done but the values in request are not available in jsp page.
Option2:
Using response.setRenderParameter I am not able to set RecordsForm type values in response.setRenderParameter to access these values in jsp page.
Can anyone please guide me which one is correct way in my case and how these values will be available in jsp page so i can load detail page.
This line of code
response.setRenderParameter("details", recordsForm);
will only pass the recordsForm object to the doView method as parameter. Your JSP is likely trying to use attributes on the RenderRequest. This means in your doView you will need to do something like the following
RecordsForm recordsForm = request.getParameter("details");
request.setAttribute("details", recordsForm);
There is also the option to use the portlet container runtime option javax.portlet.actionScopedRequestAttributes. You set this in your portlet.xml and it should take attributes you set in an action method and provide them as attributes in your render method, eliminating the need to move your objects from the parameters map to the attributes map yourself.
Unrelated note: It looks like you're using actionJsp as an object variable in your portlet. That's not recommended because portlets should be coded to be thread safe. Object variables are shared between users and threads, so saving user specific state data in them will cause errors when you get multiple users.
After adding actionScopedRequestAttributes in portlet.xml i am able to set the values in request and these values are available in jsp pages.
<container-runtime-option>
<name>javax.portlet.actionScopedRequestAttributes</name>
<value>true</value>
</container-runtime-option>
and process action is some thing like that
#ProcessAction(name = "details")
public void details(ActionRequest request, ActionResponse response) throws PortletException, IOException {
RecordsDAO recordsDAO = new RecordsDAOImpl();
int id = Integer.parseInt(request.getParameter("id"));
RecordsForm recordsForm = recordsDAO.getRecord(id);
request.setAttribute("details", recordsForm);
}

How to keep flash when redirecting to the login page

I'm implementing an email mechanism in Play:
User gets an email with a validation link
Clicks on it, gets to a controller that saves the "validated" bit on the user model, then redirects him to another page.
Before redirecting, that last page puts a message into the flash object ... to be displayed later in whatever page the user ends up at, via javascript. The message says "thanks for validating your email".
The target page has #With(Secure.class), so if the user is not authenticated I reach the Secure.login() method.
Now, at this point, I find that flash does not contain the message I just put in there before the redirection. What is the correct way to use flash in a way that survives this redirect?
This seems to work:
public class OurSecure extends Controller {
#Before(unless={"login", "authenticate", "logout"})
static void checkAccess() throws Throwable {
// Authent
if(!session.contains("username")) {
// __ my modification __ :
flash.keep();
flash.put("url", "GET".equals(request.method) ? request.url : "/");
// seems a good default
login();
}
...
}
hmm... well, its a slightly different use case, but thats the way how I remember which page the user wanted to access when he got redirected to the login page, so I can redirect him back there after successful authentication. maybe it helps
#Before(only = "authenticate")
public static void preserveUrl()
{
String url = request.params.get("url");
if(
"authenticate".equals(request.actionMethod) &&
url != null &&
!url.toLowerCase().contains("http") &&
!url.toLowerCase().contains("ftp")
)
{
flash.put("url", url);
}
}
static boolean authenticate(String username, String password) {
if(username == null || password == null)
return false;
String passwordHash = Codec.hexMD5(password.trim());
Member m = Member.findByEmailAddressPasswordHashAndStatus(username, passwordHash, Member.STATUS.ACTIVE);
return m != null;
}

Categories