I would like to add a few additional ldap attributes (actually just one) to the userdetail object. It seems like the only way to do that is to override the usercontextmapper classes which then involves extending person class and essence class within it. It seems like a little too much work just to add some additional attributes. Before pursuing that route I wanted to make sure that there isnt another easier way to accomplish this.
Basically I have an attribute called "collections" in ldap which I would like to have available on the Principal object within my application.
Thanks
You don't have to extend the internal classes if you don't want to. The only thing that the UserDetailsContextMapper requires is that the object you return from mapUserFromContext implements UserDetails.
So you should be able to just read the attributes you want (including "collections") from the LDAP context object (the DirContextOperations) and use these to create your instance.
Related
What are the pros and cons of writing class methods in grails domain classes? I am asking, because I often do not see any grails projects with methods inside the domain classes, only data members. Is there a disadvantage to doing so?
When a domain class (not just in grails, but in object oriented programming in general), this is known as an anemic domain model. Martin Fowler proposes that domain logic gets put into the domain class to create a rich domain model. By doing this, domain classes become smarter and know how to perform operations, rather than having another service class that has to operate on the domain class. The pros of having a rich domain model is that the class encapsulates more of its own behavior, and it is more self contained. On the flip side, it does make the domain class more complex. Though I think the domain class should be more than just a business object.
In grails, I tend to try to use a combination of a rich domain model and using services. It's difficult to make a blanket statement as to when a method should be in a domain class and when it should be in a service. As a general rule though, if an operation is complex and requires multiple collaborators, I'll tend to put it in a service class. If the method seems like it should be behavior on the domain class, I'll put it there.
To give a more concrete example, let's take a Person class.
class Person {
String firstName
String lastName
List<Person> friends
}
In our application a person can speak. Now I can have a TalkService that knows how a person talks. But in this case, I think that talk is a core behavior of the person, so I would add a talk method to Person.
Let's say I also have functionality where I want to find all of the friends of friends of people (2nd degree friends). To me, this is not core behavior of a Person, so I woul delegate this out to a service.
To recap, in general I would add methods to the domain class when it is core behavior of the object (e.g. is it a domain method), otherwise, I would put it in a service.
In a Java project, you must have POJO classes that represents the model.
For example: Person, Invoice, Book, ...
Then there is the service layer, which contains interfaces for users to do some database queries, it takes in parameters your Model, and also return Model, and there is the controller layer which is responsible for redirection and inject your services.
In grails, this is very easy using injection of services into your controller
Now, when do we need to use methods inside the domain classes ? it's when only the model which responsible for what do we need to do, for example, how old is a Person X (it's from the date of birth), how many items exist in a Invoice (from the List), the think is we use that only when we manipulate the data of the current object.
For save method for example, you cannot add it in your model
PersonController :
def personService
def save() {
...
Person person = ...
personService.save(person);
...
}
This is more evolutive
What I would like to do is to add some more properties(fields) for a registering user to fill out for example: we have a display name by provided by default and i would like to have some more like, place of birth, birth date and so on..
I created my own entity class and made ZfcUser working with it (to be more specific: i added some protected variables, getters and setters methods).
My problem is that i dont really know what to do next. I know that i should obviously add some elements to forms and i can do it but how can i "let know" zfcuser that i have some more variables in entity class so it can work with database well.
btw. i cant understand how this module is working for example where exactly it runs scripts which work with database
Check out CdliUserProfile it's an existing extension for ZfcUser with UserProfile support (and therefore custom properties). Check that code or use the module itself ;)
I know you can use the Authorize attribute to control access to a Controller or ActionMethod... but what about more fine grained control? It seems common to have specific fields be allowed/disallowed based on a user's role, for instance. Maybe on an employee profile the employee can edit his profile information, but only a supervisor can change his job title...
Optimally I'd like to be able to develop views, models and controllers normally and have a configuration page on the website that site admins could then use to configure authorization at whatever granularity is required. In other words the programmers shouldn't worry about it (except for the guy writing/integrating that specific part of the system.)
I can envision DisplayFor and EditorFor checking attributes to render fields as ReadOnly, Hidden, etc... and maybe the attributes get added at run time from an Authorization Provider of some kind.
The question is: Is there a framework or something out there that already does this?
Write a custom ModelMetaDataProvider that will allow you to alter the metadata for each model and it's properties before they make it to the view. The built in helpers will not render a field if it's metadata value ShowForEdit = false or ShowForDisplay = false.
You can utilize a rules engine or some other ACL to manipulate the metadata on each model and property to get most of the behavior your looking for out of the box without touching the built in helpers. On edge cases where you need more control you can write your own helpers and pass more complex data in the metadata.AdditionalValues dictionary.
You can implement security at field level using HtmlHelper. In the following example they used textbox only implementation but it can easily be extended for all type of controls:
http://bartreyserhove.blogspot.ca/2008/12/field-level-security-using-aspnet-mvc.html
I'm trying to implement a more customisable version of using ViewModel attributes and a Model Enricher to populate viewmodels lists like in this this question and associated blog post.
I would like to be able to specify the method on my select list interface from the Attribute.
Each Select List service I have returns an IEnumerable that I use to make a select list and presently exposes an All interface as the sample does. I can easily use the All method because all interfaces provide that. However I often wish to able to use other methods like the AllTradingCompanies() AllManafacturingCompanies() methods of my select list class to get filtered lists.
It is presently looking like I may have to implement a Custom attribute to map to specific e.g. [AllCompanyList] attributes but that moves me away from the nice generic method that the existing version gives me. I guess I could use it to complement it but then its starting to lose some of the charm. I also am implementing IModelEnrichers which can do custom per view model logic.
Any thoughts on a nice way to implement this?
I implemented the solution using pairs of Attributes to define a requirement for data on a ViewModel and a provider of data a repository or a service within my domain. See my follow up question asking whether this is a good idea.
in our new software project, we have the following requirement: A webpage shall show a set of data. This data shall be editable by some users (assigned to roles, i.e. manager), and only viewable by others. The tricky part is described by an example:
A User-page consists of address data and account information. The addess data shall be editable by the user and the manager and viewable by all users, while account information shall only be viewable by the actual user and the manager.
I have read a lot of information about SpringSecurity. It provides a very good framework to gran permissions on urls and methods and even domain classes. But what I need is field level ACLs. At least, that's what I think at the moment.
So, the question is: How to solve this problem using Grails?
Thanks a lot in advance,
Regards Daniel
Spring Security (Acegi Plugin) is definitely the way to go with Grails.
There is a taglib you can use that will allow a page to be different for different roles such as the following:
<g:ifUserHasRole roles="ROLE_ADMIN">
html code for extra fields
</g:ifUserHasRole>
Me, I'd encode it on the domain class, emulating the way GORM has you annotate the domain classes (static access = [field1: "ROLE_USER", field2: "ROLE_ADMIN,ROLE_USER"] as an example). Then build a method your controller could use to redact them for a given user. That method could use the domain class's annotations to decide how to redact it. Then, metaprogram it onto each of the domain classes the way plugins do.
Similarly, write the opposite method to restrict data bindings of params into the domain class, write your own data binding utility method, then metaprogram it onto each domain class as well.
Then you can just use instance.redact(user) or instance.bindData(params, user) to do what you want, and it's practically declarative syntax.
We have a similar situation and use both the ifUserHasRole tag in the gsp to drive the appropriate presentation and the we have a filter that enforces the rules based on the action being called. For example, on user controller we would only allow the management roles to call save action, or if the user.id is the same as the session.user.id. This seemed to be the best option for our situation.
What about creating an ACL class like this:
class ACL(val entry: Entry*) {
def isAccessAllowed(subject: String, permission: String): Boolean = ...
}
class Entry(val subject: String, val permission: String*)
usage:
new ACL(
new Entry("dave", "read", "write"),
new Entry("linda", "read")
)
(This example is in Scala, because I found it more expressive in this case, but it should be easy to transfer it to Groovy.)
You would then connect an ACL object with the object to be protected.