Estrutura de Projeto

Olá pessoal,
Estou bolando um sistema em que terá a seguinte possibilidade:

Projeto X
O Admin é o Joao e fazem parte do projeto, além do proprio administrador, os usuarios Pedro, Fernanda e Gilson
Projeto Y
O Admin é o Pedro e fazem parte do projeto, além do proprio administrador, os usuarios Gustavo, José e a Katia
Projeto Z
O Admin é a Maria e fazem parte do projeto, além do proprio administrador, os usuarios Rodrigo, Pedro e Ricardo

A duvida é, como que eu mapeio isso usando o Vraptor3, sendo que cada usuario/dministrador “enxergará” (ou seria “enchergará” com ‘ch’?) apenas os projetos que faz parte?

Alguém tem alguma sugestão?

O meu projeto está utilizando roles para cada usuario mas essas roles estão ligadas as funções de cada usuario, por exemplo, o administrador pode incluir usuarios no sistema, pode apagar usuarios, etc… porem o visitante só pode listar os usuarios, etc… e nao inclui esse interceptor no modelo do projeto… como faço para mapear isso? tenho que ter algo especifico no hibernate? tenho que inserir os usuarios no model do projeto? como ficaria o modelo?
Aguardo resposta.
Obrigado.
Att,
Leandro.

A solução é JAAS, que é a API do Java para autenticação e autorização. Dê uma olhada nos diversos artigos internet afora sobre JAAS.

No meu caso como uso meus projetos com EJB basta eu anotar meus EJBs com @AllowedRoles({ “ADMIN”, “SUPERVISOR”, “ETC” }) e o JAAS valida se o usuário tem tal permissão. Ele também controla a autenticação, ou seja, basta você indicar sua tabela de usuários e permissões que ele faz todo o trabalho.

Na camada web você pode validar as permissões no web.xml ou então programaticamente usando o request.isUserInRole (ou algo assim).

O Vraptor não tem nada ainda para isso. Eu tenho um plugin para Vraptor que permite unir JAAS na camada do Vraptor, porém a falta de tempo não me fez evoluir muito.

um usuário tem qtos projetos?

como vc sabe qual eh o projeto da requisição atual?

Opa!
Vim aqui responder a sua MP.
Eu uso o plugin do Bronx, é bem fácil de usar, é só colocar o jar dentro da /lib e anotar os métodos no Controller de acordo com os roles que vc quer dar permissão, por exemplo:
Quero que apenas o admin e vendedor possam cadastrar proprietários:

@Roles(roles = {"admin", "corretor"})
public void adiciona(final Proprietario proprietario) {
// codigo aqui
}

E quero que apenas o admin possa excluir:

@Roles(roles = {"admin"})
public void remove(Long idProprietario) {
// código aqui
}

Você pode anotar os métodos ou até o Controller todo:

@Resource
@Roles(roles = {"admin", "corretor"})
public class ProprietarioController {
// código aqui
}

O tópico com as dicas e o download do Restrictrex estão aqui:
http://www.guj.com.br/posts/list/149517.java

Ou vc pode tb seguir a dica do mestre Jedi Garcia e implementar com JAAS, acho que na apostila da Caelum FJ-28 têm uma parte de logins, só não lembro se têm essa parte do controle de roles.
Espero ter ajudado.
Abraço!

[quote=Guevara]Opa!
Vim aqui responder a sua MP.
Eu uso o plugin do Bronx, é bem fácil de usar, é só colocar o jar dentro da /lib e anotar os métodos no Controller de acordo com os roles que vc quer dar permissão, por exemplo:
Quero que apenas o admin e vendedor possam cadastrar proprietários:

@Roles(roles = {"admin", "corretor"})
public void adiciona(final Proprietario proprietario) {
// codigo aqui
}

E quero que apenas o admin possa excluir:

@Roles(roles = {"admin"})
public void remove(Long idProprietario) {
// código aqui
}

Você pode anotar os métodos ou até o Controller todo:

@Resource
@Roles(roles = {"admin", "corretor"})
public class ProprietarioController {
// código aqui
}

O tópico com as dicas e o download do Restrictrex estão aqui:
http://www.guj.com.br/posts/list/149517.java

Ou vc pode tb seguir a dica do mestre Jedi Garcia e implementar com JAAS, acho que na apostila da Caelum FJ-28 têm uma parte de logins, só não lembro se têm essa parte do controle de roles.
Espero ter ajudado.
Abraço![/quote]

Pessoal!!! Obrigado pela respostas!

Então mas o meu sistema ja está usando o Restrictrex do Bronx… tá funcionando legal.

O usuario X tem acesso para adicionar ou remover um projeto, o usuario Y só tem acesso para adicionar um projeto… o usuario W só tem acesso para remover um projeto… etc…

O problema é um nivel mais baixo dentro de um projeto. Por exemplo:

[list]Eu sou o Usuario Leandro e crio o projeto X e adiciono os usuario Pedro, Marcio e Katia no meu projeto.[/list]
[list]Você é o usuario Guevara que criou o projeto Y e adicionou os usuario Joao, Maria e Fernanda no seu projeto.[/list]

Os usuarios Leandro, Pedro, Marcio e Katia, ao se logarem só vão enchergar o meu projeto, assim como os usuarios Guevara, Joao, Maria e Fernanda só vão enchergar o seu projeto.

Se num outro exemplo caso tenha um usuario em comum em ambos os projetos, ele vai enchergar os dois projeto, depois do login.

Entendeu? Como que eu posso fazer isso?

Acho que tanto o JAAS quanto o Restrictrex são para controles de roles que está ok no meu projeto. Quando um usuario que nao tem permissão para adicionar um projeto tenta adicionar um projeto, o sistema vai para uma pagina de Acesso Negado… isso está ok já.

Não sei se fui bem claro na minha duvida. E um usuario com roles de “Programador”, por exemplo, pode estar em varios projetos e caso outro usuario tenha a permissão de “Coordenador” também pode criar varios projetos.

Aguardo resposta.
Obrigado.
Att,
Leandro.

vc pode fazer, em toda operação que modifica um Projeto, uma validação pra ver se o usuário atual está nesse projeto…

essa validação não precisa necessariamente estar no controller, vc pode criar um interceptor pra isso

[quote=Lucas Cavalcanti]vc pode fazer, em toda operação que modifica um Projeto, uma validação pra ver se o usuário atual está nesse projeto…

essa validação não precisa necessariamente estar no controller, vc pode criar um interceptor pra isso[/quote]

Pode ser que funcione mas eu teria que listar todos os projetos e aí caso o usuario clique num projeto que ele nao faz parte, o interceptor iria manda-lo para outra pagina de acesso negado.

Para essa verificação, (para ver se o usuario logado está no projeto requisitado pelo clique), o modelo da classe projeto teria entao que incluir um campo de List para ser mapeado no banco utilizando hibernate?

Acho que o lance seria:

Um usuário pode estar em um ou vários projetos.
Um projeto pode ter um ou vários usuários.

Ou seja, relacionamento @ManyToMany da classe Usuário para a classe Projeto Aí é só anotar isso na classe e ver o restante dos parâmetros, pode usar o EAGER:

Eu vejo dessa forma.
[]s

na verdade, na lista de projetos, vc deveria listar só os projetos que o usuário tem acesso, não todos…

não precisa ter uma lista de usuários no projeto não…
só isso é o suficiente:

Usuario usuario = dao.load(id);

result.include("projetos", usuario.getProjetos());

[quote=Lucas Cavalcanti]na verdade, na lista de projetos, vc deveria listar só os projetos que o usuário tem acesso, não todos…

não precisa ter uma lista de usuários no projeto não…
só isso é o suficiente:

[code]
Usuario usuario = dao.load(id);

result.include(“projetos”, usuario.getProjetos());
[/code][/quote]

Lucas,
Boa noite!
E essa função getProjetos? Ficaria no DAO de Usuarios e buscaria na tabela de Projetos todos os projetos que este usuario participa?
Obrigado.
Att,
Leandro.

é um dos jeitos de fazer, com o dao…

mas se vc mapeou no Usuario, vc não precisa usar o dao

[quote=Lucas Cavalcanti]é um dos jeitos de fazer, com o dao…

mas se vc mapeou no Usuario, vc não precisa usar o dao[/quote]

Entendi… acho que vai funcionar.
O problema é: dentro da tabela de projetos no banco mysql, qual a melhor maneira de guardar os usuarios que fazem parte de determinado projeto, afim de posteriormente poder buscar, pelo ID do usuario, os projetos que ele faz parte?

Crie uma tabela como usuario_projeto que contém o id do projeto e o id do usuário. Assim você faz as associações:

usuario_projeto usuario_id -> usuario.id projeto_id -> projeto.id

se vc configurar um relacionamento ManyToMany em um dos lados (usuario ou projeto) o hibernate cria essa tabela intermediária automaticamente, e já faz tudo o necessário… daí é só chamar o usuario.getProjetos() e ele vai se virar :wink: