I have a Class named Merchant which have two related fields (related in both domain and database) like so:
/**
*This class keeps information about a merchant
*/
class Merchant{
...
//The email of the merchant which is also
//as the username property of the login field
String email
//The login credentials of the merchant
UserLogin login
...
}
The Userlogin class is also defined like so
/**
*This class is used to hold the login credentials
* of a Customer, Admin or "Merchant"
*/
class UserLogin{
...
//The username used to Login
String username
//The password used to Login
String password
...
}
The Issue now is that during the addition of a new merchant, A login is also generated for the merchant using his email as the username.
I am using dynamic scaffolding but just want to add code to also update the username field of the userLogin for the merchant.
Now, when a Merchant's email is updated, The username of the login is not updated and i normally use the username to fetch the corresponding merchant after login.
How can I add a small code snippet to update the merchant's login credentials(username) when the email is changed, or is thier any way I can create a database update cascade between the email of the merchant and the username of his login.(Can I use super.update() in a controller action that I override?)
In your Merchant domain class you can add the following method to intercept an update event and if the email property has changed update the corresponding username. Off the top of my head it will look something like this:
def beforeUpdate() {
if (this.getDirtyPropertyNames().contains('email')) {
this.login.username = this.email
}
}
You can find out more information about GORM events and their hooks in the documentation.
Related
I wanted to switch to Google for Spring Security OAuth plugin from the normal username and password login . I have gone as far as letting the user login with Google and retrieve his email-address and user-name.I already have email-address as one of my entity in user table ,so how can i match the email I got from his login to the one on my domain to identify the user for spring.
The best way it's create domain that will be associate UserConnection with User. For example it will be SocialAccount. After user will login by Google+ you just need to check if exist SocialAccount for this UserConnection if yes - so you have a user, if no - create a new one
For example domain model maybe
class SocialAccount {
static belongsTo = [fan: Fan, connection: UserConnection]
}
and you should to update User class:
class User {
static hasMany = [accounts: SocialAccount]
}
Hope it will be helpful
I am currently using Asp MVC / Identity 2.0 to build a membership site.
I have made some changes that now allow a user todo the following :
Create separate username / email values on account creation
Login using either username or email through a single text field
What I am concerned about is should user Alice register an account as follows :
Username - Alice
Email - alice#example.com
User Bob could create an account as follows :
Username - alice#example.com
Email - evilbob#l33th4x0rs.com
I'd like to ensure, that should a user create an account, their username is unique in both the UserName and EmailAddress columns.
I have currently achieved within my RegisterViewModel as follows
[RegularExpression(#"^([a-zA-Z0-9 \.\&\'\-]+)$", ErrorMessage = "{0} must be alpha numeric")]
[Display(Name = "Username")]
public string UserName { get; set; }
As such it is not possible to enter an email into the username field - is this the best way to do this though?
I'm concerned that later down the line, I may want to allow some special characters in the username field.
Forgive me if this is a n00b question, I'm still very much new to this.
You cannot ensure uniqueness of your records using the Data annotations you have in your view model properties. Those are for helping validations & display purposes primarily.
What you should be doing is checking the userName value againist both UserName and Email field of your User table and allow/deny user to continue his action.
To check the userName against both email and userName fields , you might try something like this.
var userNameToCheck="alice#ss.com";
var exists=db.Users.Any(x=>x.UserName==userNameToCheck||x.Email==userNameToCheck);
if(!exists)
{
// New record. Let's continue saving it.
}
But a better solution is to use email as your username for the app(Only one column in db table) and keep a unique constraint on that column(Email) to prevent accidental duplicate entry even if your code failed to stop the duplicate entry insertion.
You should always have validation in your code and db (constraints) to be on the safer side.
I'm using Spring Security ACL in my Grails project to manage access into my application. I can create Admin and User to have different permissions into the application.
Now, I want that a particular user can see only some instances of a domain class object. That is:
following the example domain class object
class Patient
{
String name;
String surname;
...
}
Suppose that there are 3 created Patient objects.
I want that, if I login with
username = test1
password=test1
I can see only Patient that belongs to this User.
I think that is needed that, when I create a new Patient, it is stored that this Patient belongs to the User currently logged.
How can I do that?
EDIT:
Another problem is that, if I change the URL in the part of id to show, I can see all the Patient that are created. I want that, if I change URL manually, I see an access error. Is it possible?
EDIT 2:
How can I get the role of the user currently logged in? I've tried with the following code How to get current user role with spring security plugin? but I cannot perform the getAuthorities() because it tells me that it does not exists
I've solved EDIT2 in the following discussion grails exception: Tag [paginate] is missing required attribute [total]
I need to solve the EDIT1
thanks
If I understand you right you need to define belongsTo. This will create mapping in database from Patient to User.
Edit: to get current logged in user use
class SomeController {
def authenticateService
def list = {
def user = authenticateService.principal()
def username = user?.getUsername()
.....
.....
}
}
To map to user change logic in controller or use events to create mapping
Edit: edit create action:
class PatientController {
def authenticateService
...
def create() {
def patientInstance = new Patient(params)
patientInstance.user = authenticateService.principal()
...
[patientInstance: patientInstance]
}
...
}
I've got a domain-class with a user reference:
class MyThing {
MyUser createdBy
//...
And with using the Spring Security plugin, I have a fairly basic Person class setup except I'm trying to obtain the user's email address from reference. Using springSecurityService.principal works great but only for the currently logged in user.
How can I get the user's email address?
If I can't simply "lookup" by username reference, then is it possible to extend my Person class to acquire email address from the LDAP plugin and save to the database?
I solved my problem by first adding an email property to my Person class.
class MyUser {
String username
String email
Then by using a ldap template attributes map, I was able to pull the email as well as the username.
tokens.add(attributes.get("sAMAccountName").get().toString());
tokens.add(attributes.get("mail").get().toString());
From there it was just getting the property createdBy.email
In login page of spring security , I have company name , user name and password .
When i click on login button it redirects to index.jsp. I wnat to access the company name in index.jsp.
I am getting user name and password using
SecurityContextHolder.getContext().getAuthentication().getName();
and
SecurityContextHolder.getContext().getAuthentication().getCredentials();
But I wnat to retrive company name. How to do that?
Lets say that you been login and you need to get company name that you been retrieve from database. First you will need to object that implement UserDetails that will save in UserDetailsService and add any variable that you need (company, etc).
public class CustomUserDetails implements UserDetails{
private String password;
private String username;
private String companyName;
}
than at typecast with your custom Userdetails implementation.
CustomUserDetails customDetails (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getCredentials();
getCredentials will return Object of what you saved to the credential. Whatever it type you can always return it to the class you been save.