hi marek,
your use-cases are just sub-sets and are still possible with my suggestion.
instead of ResourceIdentifier i'm going to call it ResourceDescriptor.
you can implement an AccessDecisionVoter which is responsible for handling
CustomerResourceDescriptor which provides #getCustomerName.
(again: it isn't a resolver - that's something different.)
if you don't like it, you can even provide #getResource.
@ dyn. operation:
you can still do dyn. (and not type-safe) implementations - e.g.:
public class DynamicOperation implements Operation
{
private final String operationValue;
public DynamicOperation(String operationValue)
{
this.operationValue = operationValue;
}
@Override
public String toString()
{
return this.operationValue;
}
}
that's also what the el-security module can do.
-> imo
Identity#hasPermission(ResourceDescriptor, Operation) throws
AuthorizationException;
is enough (for sure we have to prototype it).
regards,
gerhard
2012/4/23 Marek Posolda <[email protected]>
> Hi all,
>
>
>
> On 22.4.2012 19:27, Christian Kaltepoth wrote:
>
>> I prefer the method signature Shane suggested in his initial mail.
>> Providing a single method with an object parameter makes most sense to
>> me:
>>
>> Identity.hasPermission(Object resource, String operation)
>>
>> This way the developer is completely free to choose how to identify
>> the resource. I think in most cases the object itself will be used.
>> And the JSF example Shane showed is a very good example for this.
>>
>> Of cause people may need other ways to refer to resources like in the
>> ResourceIdentifier concept Marek showed. But actually I see something
>> like this more as an usage pattern and I don't think it belongs
>> directly into the API. Perhaps we could provide something like
>> ResourceIdentifier as an utility class that people can use if they
>> want to refer to resources this way. But the API of Identity should be
>> as simple as possible. And the object parameter will allow people to
>> use any object they want. Even something like ResourceIdentifier.
>>
> That's the question. I think that API should be clear and using single
> method:
>
> Identity.hasPermission(Object resource, String operation)
>
>
> is not clear enough. As in some cases, your argument is directly secured
> object and in other cases it's only ResourceIdentifier for this object.
> Also it would mean that you will need to ask for the type of object in your
> PermissionResolver implementation:
>
> if (resource instanceof ResourceIdentifier)
> {
> // compute permissions for ResourceIdentifier
> }
> else
> {
> // Argument is "resource" so compute permissions for this resource
> }
>
>
>
>
> On the other hand, using single method:
> Identity.hasPermission(**ResourceIdentifier resource, Operation operation)
>
> may not be appropriate enough for some use-cases. Let's imagine that you
> have Customer and CustomerResourceIdntifier objects:
>
> public class Customer
> {
> private String ID;
> private String customerName;
>
> // getters and setters here
> }
>
> public class CustomerResourceIdentifier implements ResourceIdentifier
> {
> private String customerId;
>
> // getters and setters
> }
>
>
> And you want to create PermissionResolver, which will compute permission
> based on customer name. With the API method:
>
> Identity.hasPermission(**ResourceIdentifier resourceIdentifier, Operation
> operation)
>
>
> you can't manage to do it (unless you change implementation of
> CustomerResourceIdentifier to encapsulate customerName)
>
>
> Operation
>>
> I agree that big advantage of this approach is type-safety. On the other
> hand, using String directly is more flexible as you have more freedom.
> Let's imagine that you have some permission rules stored in database and
> you want to add new type of operation like "ADMINISTER". With using String
> as argument, you can directly create records in DB and use this new
> "ADMINISTER" argument without doing any changes in Java code. With the
> Operation approach, you would need to add this new ADMINISTER operation
> into your Operation enum:
>
>
> public enum CrudOperation implements Operation
> {
> CREATE, READ, UPDATE, DELETE, ADMINISTER
> }
>
> I wanted to point this out, but I agree that for most cases is type-safe
> approach with Operation interface probably better:-)
>
> So after all, my opinion is to have two methods:
>
> Identity.hasPermission(Object object, Operation operation) throws
> AuthorizationException;
> Identity.hasPermission(**ResourceIdentifier resourceIdentifier, Operation
> operation) throws AuthorizationException;
>
>
> Thanks,
> Marek
>