Estou olhando para o design da minha interface e estou lutando para decidir qual é a maneira mais "correta" de implementar o controle de acesso baseado em funções, dado a usere a subjectque usereles gostariam de acessar.
Tanto quanto posso ver, tenho três opções principais (com uma quarta sendo uma bastardização dos três primeiros e uma quinta sendo uma emenda do quarto):
- Consulte a
subjectlista de permissões queuserpossui -subject.allowAccess(user.getPermissionSet) - Consulte o
usercom uma lista de permissões que osubjectrequer -user.hasPermissionTo(subject.getRequiredPermissions()) - Consulte um terceiro para localizar as interseções de permissões -
accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet()) - Consulte o
subject/userenquanto delega a "decisão" para uma classe de terceiros - Tente
useracessarsubjecte gerar um erro se o acesso não for permitido
Estou inclinado para a opção quatro - subjectContenha um accessControllercampo, onde chamadas para subject.userMayAccess(User user)delegar a operação a la:
class Subject {
public function display(user) {
if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
display403(); //Or other.. eg, throw an error..
}
}
}
.. mas isso levanta outras questões:
- deve
accessControllerser um campo vs uma classe estática ..? - Deveria
subjectsaber quais permissões são necessárias para poder visualizá-lo? - onde o princípio do menor conhecimento entra em jogo aqui, com relação ao chamado
subject.display()? Os chamadores devemsubject.display()saber que o controle de acesso está em vigor? (ondesubject.display()é um "método de modelo" final) - ter
subject.display()gerenciar o controle de acesso, lançar uma exceção, onde o usuário não tem a permissão necessária?
O que seria considerado "melhor prática" nessa situação? Onde deveria ocorrer a responsabilidade pela realização das verificações?
Como esse é um exercício acadêmico que progride para a implementação, as referências aos padrões de design seriam apreciadas.