Link with hidden Id - java

I'm using Java, SpringMVC, Hibernate and MySql.
I have a question. In database i have user entity. Some User have role Admin.
If user have role Admin, can create project travel like "Go to Africa" and can join another people.
When User with admin Role login to system, in first site he see projects created by him. He can click on any project. For examle "Go to africa". Then he join friend to list.
But.
Link to a specific project look like:
ProjectXX
and in controller i have #RequestParam("idProject")
But it is really stupid solution because URL look like:
localhost:2233/managementProject?idSchool=5
If i change idSchool param in URL, i have access to someone projects.
I dont no how send this value Post method (because this is element , not form)
So I wrote a method that checks if idProject agree with project created by a person logged on:
private boolean checkAuth(int idProject,User user){
List<Project> projectList = new ArrayList<Project>(user.getProjectsAdministrators());
for(Project project:projectList){
if (project.getId_project()==idProject){
return true;
}
}
return false;
}
If true, user can add people to project. If false, modelAndView return 403 page (something like "you do not have permission"
But i don't no it is really good solution. Maybe someone have better?
Sorry for my english.
Thanks!

Related

Spring: Implement a share-via-link feature for web application

I have a requirement where I need to implement a share-application-state-via-link feature.
My application is a video streaming single page application consisting of some dropdown options for user to filter out available videos and a video player to play the selected videos.
Now first on the basis of dropdown options , a user selects the available videos and add it to video player. At max 4 videos could be added. Now after that, I need to share this state of my application to some other user so I get a share link(just like Share answer in StackOverflow) and I send this to other user. This other user just need to hit this URL and it will load the exact state of application with videos added to player and dropdown populated with respective options.
My Approach:
I have a /getVideo rest service which fetches the video data and send it as json response back to angular based frontend. I have created a Share button which when clicked, creates a link by adding all the selected dropdown options something like:
https://localhost:8080/MyApp/shared?genre=Action&type=web-series
I have created a method /shared which will take these params and call the /getVideo internally.
The problem here is, I need to load index.html when the above link is hit. I also have to send the getVideo data to be loaded with index.html and the application should function properly. Am not able to solve this problem and need help.
Is my approach correct? Is there any alternate way? Am using Spring-Boot for backend and angular2 for frontend.
Here is the /shared API:
#RequestMapping(value = "/shared", method = RequestMethod.GET)
public String getSharedVideo(RedirectAttributes redirectAttributes,
#RequestParam(value="genre", required=false) String genre,
#RequestParam(value="date", required=false) String date,
#RequestParam(value="type", required=false) String type,
#RequestParam(value="version", required=false) String version,
#RequestParam(value="category", required=false) String category
){
List<Lab> lab = null;
try {
lab = videoService.getVideo(genre, date, type, version, category);
redirectAttributes.addAllAttributes(lab); // how to send this data to frontend
return "index.html";
} catch(Exception e) {
LOGGER.error("EXCEPTION - " + e.getMessage());
}
Any help would be appreciated.

Add role to User in Liferay programmatically

I need to assign roles to my Liferay's users when they log in the application.
I have implemented all the logic in the 'authenticateByScreenName' method of a custom class that implements 'Authenticator'.
Example code:
public class ESBAuthenticator implements Authenticator{
public int authenticateByScreenName(long companyId, String screenName, String password,
Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
setProfile(companyId, screenname);
return 1;
}
public static void setProfile(long companyId, long userId){
User user = UserLocalServiceUtil.getUser(userId);
Role liferayRole = RoleLocalServiceUtil.fetchRole(companyId, "Administrator");
RoleLocalServiceUtil.addUserRole(user.getUserId(), liferayRole.getRoleId());
UserLocalServiceUtil.updateUser(user);
}
}
When I log-in, apparently it works, I check liferay database's tables and they are updated, my user has "Administrator" role assigned. However, the portal in front-end doesn't show the "Admin" option.
But If I go to 'My Account', press the 'save' button, log-out and log-in again I have the Admin options availables.
Anyone know why this happens?, I am calling 'updateUser()' after assign the role, It is not the same as the 'save' button?
Possible solution:
I have found that If I clear the content cached across the cluster it works fine. I found it in this post:
https://www.liferay.com/es/web/kamesh.sampath1/blog/-/blogs/how-to-clear-liferay-cache
Add the following line:
MultiVMPoolUtil.clear();
Anyone know if is this the right solution?, I can't find what does liferay when the "save" button from the "my_account" page is pressed. Maybe it clear this cache?. I was searching for a synchronize with database function but couldn't find anything. It seems to be that if a column is updated, liferay doesn't use it if it's cached :(.
I can give you a cheap hack.
Step 1: Make sure you have the hold of user credential.
Step 2: Do as necessary to change user roles etc
Step 3: Flush all kinds of cache (client or server) related to the flow
Step 4: redirect the user to a temp view where the user credential you held will be applied automatically and then redirected to the portal.
Lemme know whether it works
When you call the method you are passing screenName
setProfile(companyId, screenname);
But in ur setProfileMethod, you are using UserId
public static void setProfile(long companyId, long userId){
User user = UserLocalServiceUtil.getUser(userId);
Role liferayRole = RoleLocalServiceUtil.fetchRole(companyId, "Administrator");
RoleLocalServiceUtil.addUserRole(user.getUserId(), liferayRole.getRoleId());
UserLocalServiceUtil.updateUser(user);
}
Use Method
UserLocalServiceUtil.fetchUserByScreenName(companyId, screenName)
I think that the solution of clear cache works because you need to remove all cached portlets repsones. This is the way my_account do it.
// Clear cached portlet responses
PortletSession portletSession = actionRequest.getPortletSession();
InvokerPortletImpl.clearResponses(portletSession);
The problem is that InvokerPortletImpl is not visible externally. to replicate this functionally you can try a login.events.post and get the responses cache from the HttpSession e clear the map;
httprequest.getSession().getAttribute("CACHE_PORTLET_RESPONSES").clear()
but it is like a hack its better in this case MultiVMPoolUtil.clear();

Play Framework 2.4.Trying to Alter main template based User Logged in status

First thank you for reading this far.Here is a basic introduction.
I have implemented the simple authentication demo in the play 2.4 documentation.
And Here is a method where i use it.
#Security.Authenticated(Secured.class)
public Result reviewSubmit(){
//Review newReview = contactFormData.get();
//newReview.save();
Form<Review> reviewFormData = reviewForm.bindFromRequest();
User user = User.findByEmail(request().username());
if(reviewFormData.hasErrors()) {
return badRequest("Form Field has Errors" +reviewFormData);
}
Review newReview =reviewFormData.get();
newReview.user = user.fName +" " + user.lName;
newReview.save();
return redirect(routes.Reviews.review());
}
AS you can see as part of the review saving process i use
User user = User.findByEmail(request().username());
The request().username() gets the currently logged in users email address
from which i use to find the user and access there first and last names when i go to save the review object later on.
What i want to know is there a way in which i can use
if(request.username() == null ){
//Show login Button
}else{
//show Logout button
}
Inside say a main.scala.html template as an easy way of altering the main template without passing a user object from every action.
Thanks for any help or pointers provided.
N.B as i am new to play and have really struggled to understand securescoial plugins/deadbolt/play-authenticate i just want a way of obfuscating the links shown
Not sure if I am answering your question but why can't you do something like this
#if(user) {
<button>LogOut</button>
} else {
//login button
}
in your template.
Where user is passed into the template , as given in the documentation.

Using textfields and a grid in another page

I need to know how to take info from the user in one page using a label and textfield and displaying that in a grid in another page.
For example, Im getting the name of the user and displaying their name in following page in a grid. I'm using eclipse and working with vaadin, if that helps.
if what you need is an info from connected user, I suggest you to set the User object as Session Attribute.
IE:
User connectedUser = new User();
VaadinSession.getCurrent().setAttribute(User.class, connectedUser);
Then, if you need to pick this information, you just have to call
User currentUser = (User) VaadinSession.getCurrent().getAttribute(User.class);
Then, you can pick with all your getter all the required infos, like
String username = currentUser.getUsername();
In my opinion the best approach is to set the user attribute after his login, so you can have it everywhere you need to pick it from any class of your Vaadin application.
Hope this helps.
Bye

Getting a RuntimeException : Datasource user is null ? when updating User model in Play Framework 2.2.1

I am currently trying to enhance the To-Do List tutorial from Play framework's website. I've added a login form, (and of course a User class acting as a model), and it works perfectly well. I also made a small "dashboard" in which the logged user is able to change his password and his email address. But when I submit the form, I get a "Datasource user is null ?" error (RuntimeException).
The whole problem came when I wanted to restrict the edition possibilities (I first used a whole User form, which is quite over the top (User do not need to edit their ID). So I made a small inner class in my Application file called UpdateUser which gathers the required informations, just as I did for the login system.
Searching this error gave me many results but people saw their problem fixed by uncommenting the ebean.default line in the conf file, which I already did.
Here is the method I used to update user's informations :
Firstly, I made a small class in my Application to hold the form (exactly like I did for the login thing).
Then I made a update function as found here in my user class :
public static String update(String id, User newuser) {
newuser.update(id);
return("Your profile has been updated");
}
which returns the String that will be in my flash and which is according to my compiler the problem function.
This function is called in my Application like this :
public static Result updateUser(String id)
{
Form<UpdateUser> filledForm = updateUserForm.bindFromRequest();
System.out.println("Updated User : "+filledForm.get().id);
if(filledForm.hasErrors())
{
flash("success","Error while updating");
}else{
User user = new User(filledForm.get().id, filledForm.get().email, User.find.byId(filledForm.get().id).name, User.find.byId(filledForm.get().id).surname, filledForm.get().password);
flash("success", User.update(id,user));
}
return redirect(routes.Application.dashboard());
}
I tracked the data in the Form and it is not null (I mean I can get everything from the form). But I wonder if I have to create another ebean or if it's my function which is wrong. I also wonder if it's not my User creation that fail. Or maybe I should take the updateUser function and put it in my inner UpdateUser class ?
I have to admit that I worked on that all of yesterday (and probably today too), and I can't find anything on the internet except the ebean.default thing.
------EDIT
I continued to search, so here's what I tried :
1) Getting the form result into an instance of UpdateUser in order to use it
2) Use this instance instead of getting the data from the form
But it failed too. What's really weird is that I've added a toString() method for User class, and calling it on the user I want to insert (as an update) gives me the full stuff. I think it must be a configuration problem, but I can't see it.
Another thing : when I come to the error page and when I try to come back to the application by modifying the URL, I am disconnected. Is it my ebean that closes himself ?
Last edit for the day, I'm getting tired of this. I tried to delay the action (i.e. making it happen after the user has logged out), the new data are correctly saved but I still get the error when calling the update function.
Alright, I finally found it, but totally by chance.
I just had to write this :
public static String update(String id, User user) {
user.update((Object)id);
return ("Your profile has been updated");
}
Because for some reason that I don't really understand, The id String needs to be cast to Object. The rest of the code was correct. But apparently, when using update() on this particular case (is it because my id is a String or because I get the informations from another class before using it as my Model), the parameter which is supposed to be a String (even in the documentation) HAS to be cast.
That's it.

Categories