Cannot implicitly convert type 'string' to Model - asp.net-mvc-3

I keep getting these errors:
Error 1 Cannot implicitly convert type 'string' to 'NSWebSite.Models.Role'
public Role GetRoleForUser (User user)
{
if (!UserExists(user))
throw new ArgumentException(MissingUser);
return user.Roles.TargetRoleName;
}
Error 2 'NSWebSite.Models.User' does not contain a definition for 'RoleID'
User newUser = new User()
{
Name = name,
Password = FormsAuthentication.HashPasswordForStoringInConfigFile(
password.Trim(), "md5"),
Email = email,
RoleID = role.Id
};
Error 1 - I have no idea how to fix, so any advice is welcome.
Error 2 - I am getting it because my user model does not contain the definition for RoleID. If I want to set the role when I create a new user, what should I put here instead?
Below is my repository file (modified from here: brianleggDOTcom/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx) - DOT=. (dam antispam measures :-) )
http://www.mediafire.com/?gey4y9ub0v2u9nh
and my Model.Designer.cs file
http://www.mediafire.com/?qa3p9we8uqwfj09

Your Error #2 simply means that your User class has no definition for a RoleID property. Look at the class definition and you can define it there.
Your Error #1 looks like you have a method with a return type of Role, and you're trying to do:
return user.Roles.TargetRoleName; // this is a string???
If that string is what you do want to return, you'll need to modify your method like so:
string YourMethodName(...any parameters you have...)
{
// ...your code here
return SomeRole;
}
Or you can change your TargetRoleName property from type string to Role.

My first question would be: Why is this all in the same class?
I would start by sorting the classes: Role, User, etc.
You need to define what a Role is and what a User is, separately.
public class User {
private String name;,
private String password;
private String email;
private RoleID role;
public User(String name, String password, String email, RoleID role) {
this.name = name;
this.password = password;
this.email = email;
this.role = role;
}
public void someOtherMethod() {
//some code here, etc
}
}

I am kinda new to this part of MVC and C#, from the original example at: https://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx
I had changed the DB schema from a 1 to many for user and roles to a many to many relationship. Changing the DB scheme back and updating the entity schema made everything work again like from the original blog post.
Why the original poster did not separate the two classes I am not sure, but once I get things working like I want I will start looking at cleaning up the code. If some one has any suggestions about how to make the example from the above mentioned webpage work with a many to many relationship for the User and Roles, they will be greatly appreciated :-)

Related

How should I design endpoint to return different models depending on User role in Spring

So lets assume I have 2 model classes - User and Presentation, and they look something like this:
#Entity
public class Presentation {
#Id
private Long id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
}
#Entity
public class User implements UserDetails {
#Id
private Long id;
private String username;
private String name;
private String surname;
private String password;
#Enumerated(EnumType.STRING)
private Role role;
}
As you can see I have a unidirectional mapping for user in Presentation class. My endpoint looks something like this:
#RestController
public class PresentationController {
#GetMapping("/{presentationId}")
public PresentationDTO getPresentation(#PathVariable Long presentationId) {
return presentationService.getPresentationById(presentationId);
}
#GetMapping
public List<PresentationDTO> getAllPresentations() {
return presentationService.getAllPresentations();
}
}
Now for my question - how do I change getAllPresentations() to return the presentations that the users with role "user" own, and return all presentations for users with role "admin"? I know I can create a separate endpoint with a different mapping (like /admin/presentations) and add #PreAuthorize(hasRole("admin")), but here is the tricky part.
For the getAllPresentations() endpoint which everyone who is authenticated is supposed to fetch his own presentations, how do I know for which user I have to return his presentations? Maybe I can get the username as a parameter but that might be dangerous cause he can submit any username he wants and get the presentations for that user. I don't know too much about Spring Security and I don't even know the right question to ask google to get an answer so I'm stuck...
Any help will be appreciated, thanks!
You don't have to pass username to your controller method. The currently authenticated user is available through a number of different mechanisms in Spring.The simplest way to retrieve the currently authenticated principal is via a static call to the SecurityContextHolder like this :
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();
So you can refactor you method getAllPresentations() in service class to accept username as argument, and then you can load user by passed username and return presentations for that user.
One way to do what you want is to use #PostFilter annotation to filter List<Presentation> that the authenticated user owns or if the authenticated user has a role ADMIN like this:
#GetMapping
#PostFilter("filterObject.user.username == authentication.principal.username or hasRole('ADMIN')")
public List<PresentationDTO> getAllPresentations() {
return presentationService.getAllPresentations();
}

Return type of Query function in Android Room Database?

I have a simple question but I just can't find any documentation anywhere.
Suppose we have the below example, which can be found here.
#Dao
public interface UserDao {
#Query("SELECT * FROM User WHERE userId = :id")
public User getById(int id);
}
I notice the return type of the function is User, but what happens if there query doesn't return a result? (i.e. there is no user in the table with the specified id)
Will the function simply return null?
Also, if this were a Kotlin function, should the signature be the following with nullable type User?
#Query("SELECT * FROM User WHERE userId = :id")
fun getById(int id): User?
When documentation is not enough, reading sources could help.
Whatever you use (Java or Kotlin) describing Dao interface - Dao class implementation in Java (generated by Room under the hood) would be the same:
public User getById(int id) {
...
final Cursor _cursor = DBUtil.query(__db, "SELECT * FROM User ...", false, null);
.....
if(_cursor.moveToFirst()) {
// If there is at least one record
_result = new User(<...User's fields gotten from query...>);
} else {
// If there is no record
_result = null; // <---- here it is!
}
return _result;
...
}
Also, if this were a Kotlin function, should the signature be the following with nullable type User?
Technically you could omit ?, but it could mislead in reading code, so better use User? explicitly.

How to do a complicated #PreAuthorize check for an ID that is contained in child property?

According to this great post Spring-Boot #PreAuthorize allow operation only for admin or if the authenticated user id is same as path parameter id
it is shown that you can match the URL id against the user id using:
#PreAuthorize("hasRole('ROLE_ADMIN) or #authUser.id == #userId")
but what if I need to check if userId matches a child of authUser?
So suppose I have entity:
public class User {
int id;
#OneToMany(mappedBy = "owner")
Set<Store> stores;
}
and I want to validate based on #userId == #authUser.ANY_ONE_OF_THE_STORES.id?
You can create the component, for example
#Component
public class AuthComponent {
public boolean hasPermission(User user, Long id) {
// do whatever checks you want here
return someResult;
}
}
And then you can access the component method in SPEL like this
#PreAuthorize("#authComponent.hasPermission(#authUser, #userId)")
Since SPEL supports bean reference via # docs

SpringBoot: Is this correct way to save a new entry which has ManyToOne relationship?

I have two entities Person and Visit
Person has OneToMany relationship with Visit.
I was wondering if I want to save an new entry of Visit, and interm of using RestController. Is my approach correct? Or is there another way which is more efficient?
So I have the following controller which takes a VisitModel from the RequestBody, is it a correct way to call it like so?
VisitModel has the ID of person, and the needed properties for the Visit entity. I use the ID of person to look up in the personRepository for the related Person entry, whereafter I issue it to a new instance of Visit and then use the visitRepository to save it.
#RequestMapping(value="", method=RequestMethod.POST)
public String checkIn(#RequestBody VisitModel visit) {
Person person = personRepository.findById(visit.personId);
Visit newVisit = new Visit(visit.getCheckIn, person);
visitRepository.save(newVisit);
return "success";
}
The Visit entity looks as following
#Entity
public class Visit {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#JsonProperty("check_in")
private Date checkIn;
#JsonProperty("check_out")
private Date checkOut;
#ManyToOne
#JoinColumn(name="personId")
private Person person;
public Visit(Date checkIn, Person person) {
this.checkIn = checkIn;
this.person = person;
}
public Date getCheckIn() {
return checkIn;
}
public void setCheckIn(Date checkIn) {
this.checkIn = checkIn;
}
public Date getCheckOut() {
return checkOut;
}
public void setCheckOut(Date checkOut) {
this.checkOut = checkOut;
}
public Person getPerson() {
return person;
}
}
I want to know of the following approach is correct. Or is there another way which is better?
You don't need to get a Person from the database to associate it with a Visit, of course. Because of, you need to have only id of a Person to save it in the foreign key column personId.
If you use JPA EntityManager
Person person = entityManager.getReference(Person.class, visit.personId);
for Hibernate Session
Person person = session.load(Person.class, visit.personId);
This methods just create a proxy and don't do any database requests.
With Hibernate Session I used new Person(personId) as #MadhusudanaReddySunnapu suggested. Everything worked fine.
What is the difference between EntityManager.find() and EntityManger.getReference()?
Hibernate: Difference between session.get and session.load
Yes, that seems to me to be the standard way to map a bidirectional relationship. EDIT: The personId column points to the "id" field of the Person entity.Eg:
#Id
private Long id;
UPDATE: 1: The VisitModel is a 'DTO' or Data Transfer Object. Any separate package is fine. You could consider putting them into a separate jar, so that anyone using your API (with java) can use the jar to create the data before making the call. 2) The way you save it is fine as far as I can see.

Security filtering entity collection with jax-rs and jersey

I've been looking around on how to filter results based on certain security roles. I've been looking at filters but this just seems to filter out certain fields rather than the complete entity itself. Let me try to explain what I need. Lets say I have 2 entity classes:
public class Project {
private Long id;
private String name;
private String description;
// getters and setters
}
public class User {
private Long id;
private String name;
private String email;
// getters and setters
}
resource:
#Path("projects")
#Produces("application/json")
public class ProjectsResource {
#GET
public List<Project> getProjects() {
return getDetailedProjects();
}
}
Also I have 2 companies, each with their own projects. For convenience lets call them company A and company B.
What I would like to achieve is that 3 users all using this same resource get different results based on their security role.
User 1: the Super user, should get everything
User 2: manager for company A, should only get projects for company A
User 3: manager for company B, should only get projects for company B
How should I go about doing this? It just doesn't seem right to do this filtering in each resource.
I'm using jax-rs, with role based security. Users are linked to a role which grants them access to projects for a specific company.
I think you would have to parameterize your getDetailedProjectsmethod with the accessing user.
To achieve that you can inject the jersey SecurityContextinto your Resource like so (from jersey documentation):
#Path("basket")
public ShoppingBasketResource get(#Context SecurityContext sc) {
if (sc.isUserInRole("PreferredCustomer") {
return new PreferredCustomerShoppingBasketResource();
} else {
return new ShoppingBasketResource();
}
}
The securityContext.getUserPrincipal().getName()method will allow you to get hold of the requesting user and map that to a method parameter (or use it plain).

Resources