Let's say I have an ASP.NET MVC webapp that calls a repository layer, which is built on top of nHibernate. The controller passes the repository an ISecurityToken
that encapsulates the current user's identity and permissions, and the repository uses it when querying to only return rows the user should be able to see.
I want an entity (a Ticket) to only be closable by a certain group of users, as well as the user a ticket is assigned to. In other words, the hypothetical CanCloseTicket()
method needs two inputs:
ISecurityToken
Where should this hypothetical method live? I can see several possibilities but each has their drawbacks.
ticket.IsOpen
to false!" This smells bad.Ticket.IsClosed
's setter private to stop the same thing above from happening. The repository lives in a totally different assembly than the model so using an internal setters won't work. I could instead leave the setter public and compare the property's current value to its original one, returning an error if an unprivileged user closes it, but this also smells a bit off to me. ("Oops, I forgot to check the return value of repo.CloseTicket()
in this action method!")Ticket.Close(ISecurityToken token)
and making the entity responsible for its own security logic feels like a violation of SRP.I think the repository is the best option here, but it feels more like the least-worst option. Is there anything else?
Your final option sounds exactly right to me: when someone wants to close a ticket, they have to provide evidence in the form of a security token. (Having said that, it's hard enough to judge SRP violations when you have access to a class' source code that I can't say I'm totally confident.)