package br.com.dextra.dextranet.grupo; import java.io.IOException; import java.net.URISyntaxException; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.json.simple.JSONArray; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import br.com.dextra.dextranet.grupo.servico.google.Aprovisionamento; import br.com.dextra.dextranet.grupo.servico.google.GoogleGrupoJSON; import br.com.dextra.dextranet.rest.config.Application; import br.com.dextra.dextranet.seguranca.AutenticacaoService; import br.com.dextra.dextranet.usuario.Usuario; import br.com.dextra.dextranet.usuario.UsuarioRepository; import com.google.api.services.admin.directory.model.Group; import com.google.api.services.admin.directory.model.Member; import com.google.appengine.api.datastore.EntityNotFoundException; @Path("/grupo") public class GrupoRS { GrupoRepository repositorio = new GrupoRepository(); MembroRepository repositorioMembro = new MembroRepository(); ServicoGrupoRepository servicoGrupoRepository = new ServicoGrupoRepository(); UsuarioRepository usuarioRepository = new UsuarioRepository(); private Aprovisionamento aprovisionamento = new Aprovisionamento(); @GET @Path("/{id}") @Produces(Application.JSON_UTF8) public Response obter(@PathParam("id") String id) throws EntityNotFoundException { Grupo grupo = repositorio.obtemPorId(id); List<Membro> membros = repositorioMembro.obtemPorIdGrupo(grupo.getId()); List<ServicoGrupo> servicoGrupos = servicoGrupoRepository.obtemPorIdGrupo(grupo.getId()); grupo.setMembros(membros); grupo.setServicoGrupos(servicoGrupos); return Response.ok().entity(grupo.getGrupoJSON()).build(); } @GET @Path("/") @Produces(Application.JSON_UTF8) public Response listar() throws EntityNotFoundException { List<Grupo> grupos = repositorio.lista(); List<GrupoJSON> gruposRetorno = new ArrayList<GrupoJSON>(); UsuarioRepository repositorioUsuario = new UsuarioRepository(); for (Grupo grupo : grupos) { List<Membro> membros = repositorioMembro.obtemPorIdGrupo(grupo.getId()); List<ServicoGrupo> servicoGrupos = servicoGrupoRepository.obtemPorIdGrupo(grupo.getId()); // TODO: faria mais sentido esse codigo estar dentro de algum // repositorio for (Membro membro : membros) { try { Usuario integranteDoGrupo = repositorioUsuario.obtemPorId(membro.getIdUsuario()); membro.setNomeUsuario(integranteDoGrupo.getNome()); } catch (EntityNotFoundException e) { repositorioMembro.remove(membro.getId()); } } grupo.setMembros(membros); grupo.setServicoGrupos(servicoGrupos); gruposRetorno.add(grupo.getGrupoJSON()); } return Response.ok().entity(gruposRetorno).build(); } @PUT @Path("/googlegrupos/") @Consumes("application/json") @SuppressWarnings("unchecked") public Response aprovisionarServicos(List<GoogleGrupoJSON> googleGrupoJSONs) throws IOException, ParseException, GeneralSecurityException, URISyntaxException { for (GoogleGrupoJSON googleGrupoJSON : googleGrupoJSONs) { Group grupo = aprovisionamento.obterGrupo(googleGrupoJSON.getEmailDomainGrupo()); List<String> emails = new ArrayList<String>(); if (grupo == null) { grupo = aprovisionamento.criarGrupo(googleGrupoJSON.getEmailGrupo(), googleGrupoJSON.getEmailDomainGrupo(), ""); } List<Member> membros = aprovisionamento.obterMembros(grupo); for (UsuarioJSON usuarioJSON : googleGrupoJSON.getUsuarioJSONs()) { String email = usuarioJSON.getEmail(); if (!ehMembro(membros, email)) { emails.add(email); } } if (googleGrupoJSON.getEmailsExternos() != null) { JSONParser jParser = new JSONParser(); JSONArray emailsExternos = (JSONArray) jParser.parse(googleGrupoJSON.getEmailsExternos()); Iterator<String> emailExterno = emailsExternos.iterator(); while (emailExterno.hasNext()) { String email = emailExterno.next(); if (!ehMembro(membros, email)) { emails.add(email); } } } aprovisionamento.adicionarMembros(emails, grupo); } return Response.ok().build(); } private boolean ehMembro(List<Member> membros, String email) { if (membros != null) { for (Member membro : membros) { if (membro.getEmail().equals(email)) { return true; } } } return false; } @PUT @Consumes("application/json") @Path("/googlegrupos/removerIntegrantes/") public Response removerIntegrantes(List<GoogleGrupoJSON> googleGrupoJSONs) throws IOException, ParseException, GeneralSecurityException, URISyntaxException { for (GoogleGrupoJSON googleGrupoJSON : googleGrupoJSONs) { List<String> emails = new ArrayList<String>(); if (googleGrupoJSON.getUsuarioJSONs() != null) { for (UsuarioJSON usuarioJSON : googleGrupoJSON.getUsuarioJSONs()) { emails.add(usuarioJSON.getEmail()); } } if (googleGrupoJSON.getEmailsExternos() != null) { emails.add(googleGrupoJSON.getEmailsExternos()); } Group grupo = aprovisionamento.obterGrupo(googleGrupoJSON.getEmailDomainGrupo()); aprovisionamento.removerMembros(emails, grupo); } return Response.ok().build(); } @GET @Path("/googlegrupos/listarGrupos") @Produces(Application.JSON_UTF8) public Response listaTodosGrupos() throws IOException, GeneralSecurityException, URISyntaxException { List<Group> groups = aprovisionamento.obterGrupos("dextra-sw.com"); List<String> emailGrupos = new ArrayList<String>(); for (Group group : groups) { emailGrupos.add(group.getEmail()); } return Response.ok(emailGrupos).build(); } @GET @Produces(Application.JSON_UTF8) @Path("/googlegrupos/listarMembrosGrupo/{email}") public Response listaMembrosGrupo(@PathParam("email") String email) throws IOException, GeneralSecurityException, URISyntaxException { Group grupo = aprovisionamento.obterGrupo(email); List<Member> members = aprovisionamento.obterMembros(grupo); List<String> emailsMembros = new ArrayList<String>(); for (Member member : members) { emailsMembros.add(member.getEmail()); } return Response.ok().entity(emailsMembros).build(); } @DELETE @Produces(Application.JSON_UTF8) @Path("/googlegrupos/grupo/{idGrupo}/servico/{idServicoGrupo}") public Response removerServico(@PathParam("idGrupo") String idGrupo, @PathParam("idServicoGrupo") String idServicoGrupo) throws EntityNotFoundException, IOException, GeneralSecurityException, URISyntaxException { String usuarioLogado = obtemUsernameUsuarioLogado(); Grupo grupo = repositorio.obtemPorId(idGrupo); if (podeRemoverServico(usuarioLogado, grupo)) { ServicoGrupo servico = servicoGrupoRepository.obtemPorId(idServicoGrupo); aprovisionamento.removerGrupo(servico.getEmailGrupoDomain()); servicoGrupoRepository.remove(idServicoGrupo); return Response.ok().build(); } else { return Response.status(Status.FORBIDDEN).build(); } } @PUT @Path("/") @Consumes("application/json") public Response adicionar(GrupoJSON grupojson) throws ParseException { Grupo grupo = new Grupo(grupojson.getNome(), grupojson.getDescricao(), obtemUsernameUsuarioLogado()); repositorio.persiste(grupo); for (UsuarioJSON usuariojson : grupojson.getUsuarios()) { Membro membro = new Membro(usuariojson.getId(), grupo.getId(), usuariojson.getNome(), usuariojson.getEmail()); repositorioMembro.persiste(membro); } if (grupojson.getServico() != null) { for (GoogleGrupoJSON servico : grupojson.getServico()) { ServicoGrupo servicoGrupo = new ServicoGrupo(servico.getIdServico(), grupo.getId(), servico.getEmailGrupo(), servico.getEmailsExternos()); servicoGrupoRepository.persiste(servicoGrupo); } } return Response.ok().build(); } @PUT @Path("/{idGrupo}") @Produces(Application.JSON_UTF8) public Response atualizar(@PathParam("idGrupo") String id, GrupoJSON grupojson) throws EntityNotFoundException { grupojson.setId(id); String usernameLogado = obtemUsernameUsuarioLogado(); String proprietario = usernameLogado; Grupo grupo = repositorio.obtemPorId(id); if (podeAlterarGrupo(usernameLogado, grupo)) { if (proprietarioExcluido(grupojson)) { grupo.comProprietario(obterNovoProprietarioGrupo(grupo)); } if (!grupo.getProprietario().equals(usernameLogado)) { proprietario = grupo.getProprietario(); } grupo = grupo.preenche(grupojson.getNome(), grupojson.getDescricao(), proprietario); repositorio.persiste(grupo); adicionaNovosMembros(grupojson.getUsuarios(), grupo.getId()); persisteServicoGrupo(grupojson, grupo); return Response.ok().build(); } else { return Response.status(Status.FORBIDDEN).build(); } } @DELETE @Path("/{id}") @Produces(Application.JSON_UTF8) public Response remover(@PathParam("id") String id) throws EntityNotFoundException, IOException, GeneralSecurityException, URISyntaxException { String usuarioLogado = obtemUsernameUsuarioLogado(); Grupo grupo = repositorio.obtemPorId(id); if (podeDeletarGrupo(usuarioLogado, grupo)) { List<Membro> obtemPorIdGrupo = repositorioMembro.obtemPorIdGrupo(id); for (Membro membro : obtemPorIdGrupo) { repositorioMembro.remove(membro.getId()); } List<ServicoGrupo> servicoGrupos = servicoGrupoRepository.obtemPorIdGrupo(id); if (!servicoGrupos.isEmpty()) { for (ServicoGrupo servico : servicoGrupos) { aprovisionamento.removerGrupo(servico.getEmailGrupoDomain()); servicoGrupoRepository.remove(servico.getId()); } } repositorio.remove(id); return Response.ok().build(); } else { return Response.status(Status.FORBIDDEN).build(); } } protected String obtemUsernameUsuarioLogado() { return AutenticacaoService.identificacaoDoUsuarioLogado(); } protected Usuario obtemUsuarioLogado() { return AutenticacaoService.identificacaoDoUsuarioLogado(obtemUsernameUsuarioLogado()); } private String obterNovoProprietarioGrupo(Grupo grupo) throws EntityNotFoundException { List<Membro> membros = repositorioMembro.obtemPorIdGrupo(grupo.getId()); for (Membro membro : membros) { if (!membro.getEmail().equals(grupo.getProprietario())) { return membro.getEmail(); } } // TODO: VERIFICAR ESSE PONTO QUANDO NÃO EXISTIR NENHUM MEMBRO return null; } private Boolean proprietarioExcluido(GrupoJSON grupoJson) { String proprietarioAtualGrupo = grupoJson.getProprietario(); Usuario usuario = usuarioRepository.obtemPorUsername(proprietarioAtualGrupo); Membro membroProprietario = new Membro(null, grupoJson.getId(), usuario.getNome(), usuario.getUsername()); if (proprietarioEstavaNoGrupo(grupoJson, membroProprietario)) { List<UsuarioJSON> membros = grupoJson.getUsuarios(); for (UsuarioJSON membro : membros) { if (membro.getEmail().equals(membroProprietario.getEmail())) { return Boolean.FALSE; } } return Boolean.TRUE; } else { return Boolean.FALSE; } } private Boolean proprietarioEstavaNoGrupo(GrupoJSON grupoJson, Membro membroProprietario) { Membro proprietario = repositorioMembro.obtemPorUsername(membroProprietario.getEmail(), grupoJson.getId()); if (proprietario != null) { return Boolean.TRUE; } return Boolean.FALSE; } private void persisteServicoGrupo(GrupoJSON grupojson, Grupo grupo) throws EntityNotFoundException { if (grupojson.getServico() != null) { for (GoogleGrupoJSON servico : grupojson.getServico()) { Boolean novoRegistro = true; if (servico.getId() != null && servico.getEmailsExternos() != null) { ServicoGrupo servicoGrupo = servicoGrupoRepository.obtemPorId(servico.getId()); servicoGrupo = servicoGrupo.preenche(servico.getEmailsExternos()); servicoGrupoRepository.persiste(servicoGrupo); novoRegistro = false; } else if (servico.getEmailsExternos() != null && novoRegistro) { ServicoGrupo servicoGrupo = new ServicoGrupo(servico.getIdServico(), grupo.getId(), servico.getEmailGrupo(), servico.getEmailsExternos()); servicoGrupoRepository.persiste(servicoGrupo); } else { ServicoGrupo servicoGrupo = new ServicoGrupo(servico.getIdServico(), grupo.getId(), servico.getEmailGrupo()); servicoGrupoRepository.persiste(servicoGrupo); } } } } private void adicionaNovosMembros(List<UsuarioJSON> usuarios, String idGrupo) throws EntityNotFoundException { List<Membro> membros = repositorioMembro.obtemPorIdGrupo(idGrupo); deletaMembros(usuarios, membros); adicionarEAtualizarMembros(usuarios, idGrupo); } private void adicionarEAtualizarMembros(List<UsuarioJSON> usuarios, String idGrupo) { // TODO: Verificar uma forma de adicionar somente os necessários for (UsuarioJSON usuario : usuarios) { Membro membroAtualizar = new Membro(usuario.getId(), idGrupo, usuario.getNome(), usuario.getEmail()); repositorioMembro.persiste(membroAtualizar); } } private void deletaMembros(List<UsuarioJSON> usuarios, List<Membro> membros) { // TODO Verificar uma forma de somente remover os que não existem na // tela for (Membro membro : membros) { repositorioMembro.remove(membro.getId()); } } private boolean podeDeletarGrupo(String usuarioLogado, Grupo grupo) { return AutenticacaoService.isUsuarioGrupoInfra() || usuarioLogado.equals(grupo.getProprietario()); } private boolean podeRemoverServico(String usuarioLogado, Grupo grupo) { return podeDeletarGrupo(usuarioLogado, grupo); } private boolean podeAlterarGrupo(String usuarioLogado, Grupo grupo) { Boolean isMembroGrupo = repositorioMembro.obtemPorUsername(usuarioLogado, grupo.getId()) != null; return podeDeletarGrupo(usuarioLogado, grupo) || isMembroGrupo; } }