Good stuff, glad that helped. Perhaps you could do a blog post or just share the code on github, then I could reference from the site.
Cheers Dan On 4 April 2014 19:21, Erik de Hair <[email protected]> wrote: > That works quit well. Thanks a lot! > > It's also a good example to start exploring the crypts of Isis :-) > > Erik > > ________________________________________ > From: Dan Haywood [[email protected]] > Sent: Friday, April 04, 2014 2:42 PM > To: users > Subject: Re: per instance security > > On 4 April 2014 13:16, Erik de Hair <[email protected]> wrote: > > > Hi Dan, > > > > The sequence of actions executed by Isis during application execution is > > unclear to me. Furthermore All examples look method/member based to me > and > > I have no clue how to hook into this sequence for hiding instances (or > deny > > access). > > > > > You can get the current instance (which is called ObjectAdapter - a wrapper > around the pojo domain object) from the supplied *Context. > > All together it'd be something like... > > > public interface SecuredPerInstance { ... } > > > public class PerInstanceDisabilityFacetFactory extends FacetFactoryAbstract > { > > ... > > @Override > public void process(final ProcessMethodContext processMethodContext) { > final FacetedMethod member = processMethodContext.getFacetHolder(); > final Class<?> owningClass = processMethodContext.getCls(); > > if(SecuredPerInstance.class.isAssignableFrom(owningClass)) { > FacetUtil.addFacet(new PerInstanceDisabilityFacet(member)); > } > } > > } > > > > public class PerInstanceDisabilityFacet extends FacetAbstract implements > DisablingInteractionAdvisor { > > @Override > public String disables(final UsabilityContext<? extends UsabilityEvent> > ic) { > if (!(ic instanceof UsabilityContext)) { > return null; > } > final ObjectAdapter target = ic.getTarget(); > final SecuredPerInstance pojo = > (SecuredPerInstance)target.getObject(); > > // hacky... > final String currentUser = > > IsisContext.getPersistenceSession().getServicesInjector().getContainer().getUser(); > > return poco.usableBy(currentUser) ? null: "Sorry, you can't modify > this instance."; > } > > > > > > > > > I think this is a bit too complex right now. I'm new to Isis and normally > > I would start doing more easy stuff to learn using Isis. But if we don't > > have 'per instance security' we can't use Isis. Is there any > documentation > > about the principles of using these facet(factorie)s? > > > > > Nothing other than the doc I've already referenced, and the source code > itself :-) > > > But perhaps the above will help; it should be possible to implement in > about 30 lines of code or so... > > Dan > > > > > > > Thanks, > > Erik > > > > > > ________________________________________ > > From: Dan Haywood [[email protected]] > > Sent: Friday, April 04, 2014 11:52 AM > > To: users > > Subject: Re: per instance security > > > > On 4 April 2014 10:39, Erik de Hair <[email protected]> wrote: > > > > > Hi Dan, > > > > > > Your last option seems the most feasible option to me. > > > > > > I presume I write my own permission-implementation then (for every > domain > > > class if necessary) to be used by "public List<String> visibleTo();"? > > > > > > Would really like you to guide me. Where to start? > > > > > > > > Ultimately, all you need is an implementation of FacetFactory to be > > registered in ProgrammingModel, where the FacetFactory installs a Facet > on > > the metamodel members that implements HidingInteractionAdvisor or > > DisablingInteractionAdvisor. > > > > To do the registration, see [1]. > > > > In terms of the FacetFactory, you could base it on something > > like HiddenFacetViaHideMethodFacetFactory, which is called for all > members. > > You'll need to get the class of the member (from ProcessMethodContext > > argument) to determine whether the class itself implements the interface > > (if not, ignore). > > > > In terms of the Facet, it merely must implement the *InteractionAdvisor > > interfaces. The existing HiddenFacet* and DisablingFacet* do this, but > > they are quite complex; a better option might be to use > > AuthorizationFacetAbstract for inspiration. > > > > Let me know how you get on. > > > > Dan > > > > > > [1] > > > > > http://isis.apache.org/more-advanced-topics/metamodel-finetuning-the-programming-model.html > > > > > > > > > > > > ________________________________________ > > > From: Dan Haywood [[email protected]] > > > Sent: Friday, April 04, 2014 10:26 AM > > > To: users > > > Subject: Re: per instance security > > > > > > On 4 April 2014 09:03, Erik de Hair <[email protected]> wrote: > > > > > > > Hi, > > > > > > > > I need per instance security in my application. What I want to do is > > > > extend AuthorisationRealm with doGetAuthorisationInfo() and implement > > my > > > > own permissions-scheme to check for the users permissions for a > certain > > > > domain model instance. > > > > > > > > > > > I'm not sure that's the way to solve this. > > > > > > With Shiro, the permission strings correspond to class members > (possibly > > > wildcarded to all members in a class, or to all classes in a package > > etc). > > > So it is a class-based security mechanism, not an instance-based one. > > > > > > That said, the way in which Shiro parses the permission string is > > > pluggable, so in theory one could have a different permission scheme > that > > > includes the OIDs of objects (Company/L_10). But I don't think it'd > be a > > > very maintainable approach (lots of fiddly data to setup). > > > > > > So I feel a better way to address this is up a level, within Isis.... > > > > > > > > > Do I have to check for these permissions myself > > > > > > > > > You could, if you wanted, put the code in the domain objects, eg in the > > > hide or disable methods, and get hold of the current user from > > > getContainer(). But that would litter your domain code with lots of > > > security stuff, which sounds unappealing. > > > > > > Or... what I would probably explore is if there is some sort of > > convention > > > whereby you could write a custom facet (implementing > > > HidingInteractionAdvisor or DisablingInteractionAdvisor) such that you > > > could do the per-instance security as a cross-cutting concern. > > > > > > For example, each object that requires per-instance security could > > > implement an interface: > > > > > > public interface SecuredPerInstance { > > > > > > // return the user or roles that this instance is visible for > > > @Programmatic > > > public List<String> visibleTo(); > > > > > > // return the user or roles that this instance can be used by > > > (modifiable, invoke actions) > > > @Programmatic > > > public List<String> usableBy(); > > > } > > > > > > Then classes that need security would implement this instance, and the > > > facet would advise based on the facet. > > > > > > If that makes sense, I can guide you in writing such a facet if need > be. > > > > > > HTH > > > Dan > > > > > > > > > and throw a security exception in case of no permission or is this > > > > automatically done by Shiro when a client calls the restful interface > > > like: > > > > > > > > http://localhost:8080/restful/objects/nl.pocos.dom.Company/L_10 > > > > > > > > Regards, > > > > Erik > > > > > > > > > >
