The user name is stored in an a connected object - grails

I'm using grails and I have the following domain classes:
class User {
transient springSecurityService
String password
static belongsTo = [person: Person]
}
And
class Person {
String name
String emailAddress
....
}
I would like to use the person object's email address as the username in Spring Security.
According to the Spring Security manual, that just takes setting the property of grails.plugins.springsecurity.userLookup.usernamePropertyName to the non-"username" field.
I've tried person.emailAddress, and that doesn't work.
How can I get Spring security to use the Person reference to the User? I can't put the password on the Person class, and I've tried to use inheritance (that brings up other issues).
So I've traced this down to GormUserDetailsService, where this is being called and implimented. The code that is used to find the user is:
def user = User.findWhere((conf.userLookup.usernamePropertyName): username)
if (!user) {
log.warn "User not found: $username"
How would I structure the userNamePropertyName so that I could get it look through the child property?

It's bad idea. Just replace email to User, but if you want to use this field in person, create link to this field.
class User {
transient springSecurityService
String password
String email
static belongsTo = [person: Person]
}
and Person:
class Person {
String name
String emailAddress
....
String getEmail(){
user.email //if relations OneToOne
}
static hasOne = [user:User] //if relations OneToOne
}
You should stay relations OneToOne, because I can't imaginate in what case it should be OneToMany
UPD. Or you can try try this one:
class User extends Person{..}
and in spring security config write just email, but i'm not sure.

Related

Grails findBy query with foreign key

I'm trying to fetch a user profile picture from the DB by calling the getProfiePicture() method on User object.
Method call from view:
<p>${user.getProfilePicture()}</p>
User.groovy domain class:
class Picture {
User user
String url
boolean profile = false
boolean verified = true
static belongsTo = [user: User]
static constraints = {
}
}
Picture.groovy domain class:
class User {
static hasMany = [pictures: Picture]
String uid = UUID.randomUUID().toString()
String username
String password
String getProfilePicture() {
log.debug("ID: " + id)
log.debug("UID: " + uid)
log.debug("Pictures: " + pictures)
return Picture.findByUserIdAndProfile(id, true)
}
}
Picture table:
Problem
I'm getting this error when I'm trying to get the profile picture:
Class
org.codehaus.groovy.grails.exceptions.InvalidPropertyException
Message
No property found for name [userId] for class [class foo.Picture]
What am I doing wrong?
I'm using:
Grails 2.4.4
The getProfilePicture() method inside your User domain class should return the following:
Picture.findByUserAndProfile(this, true)
The reason you're getting that error is because you are trying to find a Picture instance by userId, a field which doesn't exist.
You can implement getProfilePicture as following:
String getProfilePicture() {
Picture.where { user == this && profile == true}.first().url
}
Alternatively you can use a dynamic Finder (as shown in the comments). By the way: the Picture Class does not need to create the user Attributes twice. static belongsTo = [user: User] is enough.

View grails domain class property in another domain class

Hi I am just trying out grails and trying to learn more on domain class. I have two simple domain classes:
Domain Class 1
package grailtest
class Person {
String firstName
String lastName
int age
String email
static constraints = {
}
}
Domain Class 2
package grailtest
class Customer {
String customerId
Person personInCharge
static constraints = {
}
}
When I do a run-app, I can only see
grailtest.Person : 1
as the Person. How can I default it to a particular value, for instance firstName + lastName, to make the application more user friendly?
in the domain override toString method to what you wanted to be display. restart the app
You can use #ToString in case you want an elaborative way of logging or printing in standard out.
import groovy.transform.ToString
#ToString(includeNames=true, includeFields=true)
class Person {
String firstName
String lastName
int age
String email
}
For example,
def person = new Person(firstName: 'Test', lastName: 'hola',
age: 10, email: 'abc#xyz.com')
would give
Person(firstName:Test, lastName:hola, age:10, email:abc#xyz.com)
Find the view where it displays grailstest.Person: 1 and update it to:
${personInstance.firstName} ${personInstance.lastName}
By default this view should be in "views/person"
You put this code in the view .gsp
${personInstance?.firstname} ${personInstance?.lastname}

Prevent grails from fetching domain object

I have an image which belongs to a user
class Image {
static belongsTo = [user: User]
String name
String path
}
class User {
String name
}
How can I get the user Id without fetching the user in the database :
myService.doIt(Image.get(1).user.id)
fetches the user (I just need the id here)
Use the dynamic "fooId" property for a domain class property "foo":
myService.doIt(Image.get(1).userId)

Grails: master domain field by detail domain field [hasMany]

There are domains:
class Order {
static hasMany = [execDepartments: Department]
String orderNo
//boolean signature
...
}
class Department {
String name
...
}
I want to add boolean signature field for Order but by Department, so I need field signature by execDepartments for Order. Is it possible? Please help.
Is this an m:m relationship?
why not create another domain like
class Order {
static hasMany = [execDepartments: DepartmentOrder]
String orderNo
//boolean signature
...
}
class DepartmentOrder{
boolean signature
Order order
Department department
}
class Department {
String name
static hasMany = [execOrders: DepartmentOrder]
}
Then you can write the belongTo
What you need is a list of signatures in the Order domain.
Possibly an OrderSignature domain that maps signatures to orders.

grails - how to save ArrayList in db

I use grails-1.3.2 and hbase plugin.
I have some difficulty in creating one-to-Many association with
hbase (i can work with hibernate), so
i decided to try create one-to-Many association with using ArrayList.
Here are my domain classes and controllers:
class Contacts {
String con
static constraints = {}
}
class ContactsController {
def create = {
def contact = new Contacts()
contact.con = params.con
contact.save(flush:true)
}
}
class User {
String firstname
String lastname
// static hasMany = [contact: Contacts]
static ArrayList<Contacts> contact
static constraints = {}
}
class UserController{
def create = {
def user = new User()
user.properties = params
user.save(flush: true)
}
def addContact = {
def user = User.get(params.userID)
def contact = Contacts.get(params.contactID)
user.contact.add(contact)
user.save(flush:true)
}
}
In addContact action user.contact = null, so it can not work.
In user does nor appear contact field.
Can someone help me understand what i have to do for saving ArrayList in db?
I don't know anything about hbase, but the static contact property of the User class looks very suspicious. The fact that this property is static, implies that every user has the same contact list, which seems unlikely to be the desired behaviour.
In a standard GORM domain model - assuming you want each User to have their own contact list - this would be defined
class User {
String firstname
String lastname
static hasMany = [contact: Contacts]
}
Although it looks like we're also defining a static property here, it's actually just the definition of how the Contact and User classes are related (AKA mapping) that is static. The contact property that is dynamically added to the User class is non-static.
Aside
I recommend renaming the Contacts class to Contact and the contact property to contacts. The GORM mapping would then look like this:
class User {
String firstname
String lastname
static hasMany = [contacts: Contact]
}

Resources