From e2f6c3260fe03b6692c8df92487f5ed022c67a59 Mon Sep 17 00:00:00 2001 From: Braga Date: Thu, 19 Jun 2025 17:04:58 -0300 Subject: [PATCH] Add files via upload --- Main.java | 50 +- Makefile | 2 +- bin/Main.class | Bin 0 -> 7735 bytes .../CaminhoJaExistenteException.class | Bin 0 -> 264 bytes .../CaminhoNaoEncontradoException.class | Bin 0 -> 268 bytes bin/exception/PermissaoException.class | Bin 0 -> 246 bytes bin/filesys/FileSystem.class | Bin 0 -> 1950 bytes bin/filesys/FileSystemImpl.class | Bin 0 -> 12684 bytes bin/filesys/IFileSystem.class | Bin 0 -> 858 bytes exception/CaminhoJaExistenteException.java | 2 + exception/CaminhoNaoEncontradoException.java | 2 + exception/PermissaoException.java | 2 + filesys/FileSystem.java | 19 +- filesys/FileSystemImpl.java | 499 +++++++++++++++++- filesys/IFileSystem.java | 1 + tests/PermissionTest.java | 274 +++++++++- users/users | 10 +- 17 files changed, 823 insertions(+), 38 deletions(-) create mode 100644 bin/Main.class create mode 100644 bin/exception/CaminhoJaExistenteException.class create mode 100644 bin/exception/CaminhoNaoEncontradoException.class create mode 100644 bin/exception/PermissaoException.class create mode 100644 bin/filesys/FileSystem.class create mode 100644 bin/filesys/FileSystemImpl.class create mode 100644 bin/filesys/IFileSystem.class diff --git a/Main.java b/Main.java index 3b8673a..fd95f7d 100644 --- a/Main.java +++ b/Main.java @@ -1,5 +1,7 @@ -import filesys.IFileSystem; +import filesys.*; +import java.util.HashMap; +import java.util.Map; import java.util.Scanner; import java.io.FileNotFoundException; @@ -7,15 +9,15 @@ import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; -import filesys.FileSystem; - // MENU INTERATIVO PARA O SISTEMA DE ARQUIVOS // SINTA-SE LIVRE PARA ALTERAR A CLASSE MAIN + public class Main { // Constantes úteis para a versão interativa. // Para esse tipo de execução, o tamanho max do buffer de // leitura pode ser menor. + private static final String ROOT_USER = "root"; private static final String ROOT_DIR = "/"; private static final int READ_BUFFER_SIZE = 256; @@ -31,15 +33,16 @@ public class Main { // O sistema de arquivos é inteiramente virtual, ou seja, será reiniciado a cada execução do programa. // Logo, não é necessário salvar os arquivos em disco. O sistema será uma simulação em memória. + public static void main(String[] args) { // Usuário que está executando o programa. // Para quaisquer operações que serão feitas por esse usuário em um caminho /path/**, // deve-se checar se o usuário tem permissão de escrita (r) neste caminho. - if (args.length < 2) { + if (args.length < 1) { System.out.println("Usuário não fornecido"); return; } - user = args[1]; + user = args[0]; // Carrega a lista de usuários do sistema a partir de arquivo // Formato do arquivo users: @@ -51,6 +54,9 @@ public static void main(String[] args) { // A partir do momento que um usuário cria outro diretório ou arquivo, // a permissão desse usuário é de leitura, escrita e execução nesse novo diretório/arquivo, // e sempre será rwx para o usuário root. + + Map> permissoes = new HashMap<>(); + try { Scanner userScanner = new Scanner(new java.io.File("users/users")); while (userScanner.hasNextLine()) { @@ -61,11 +67,20 @@ public static void main(String[] args) { String userListed = parts[0]; String dir = parts[1]; String dirPermission = parts[2]; + + // Ajuste aqui: + if (dir.equals("/**")) { + dir = "/"; + } /* A FAZER: * Processar a permissão de todos os usuários existentes por diretório. * Por enquanto esse código somente imprime as permissões contidas no arquivo users. */ + + permissoes.putIfAbsent(dir, new HashMap<>()); + permissoes.get(dir).put(userListed, dirPermission); + System.out.println(userListed + " " + dir + " " + dirPermission); // Somente imprime o usuário, diretório e permissão @@ -80,19 +95,30 @@ public static void main(String[] args) { return; } + + // Verifica se o usuário existe em alguma permissão, exceto root + boolean usuarioExiste = user.equals(ROOT_USER) || permissoes.values().stream() + .anyMatch(mapUserPerm -> mapUserPerm.containsKey(user)); + + if (!usuarioExiste) { + System.out.println("Usuário não fornecido ou inexistente."); + return; + } + // Usuário Importante // Finalmente cria o Sistema de Arquivos // Lista de usuários é imutável durante a execução do programa // Obs: Como passar a lista de usuários para o FileSystem? - fileSystem = new FileSystem(/*usuários?*/); + fileSystem = new FileSystem(permissoes); // passar o mapa de permissoes ao criar o FileSystem ; fileSystem = new FileSystem(/*usuários?*/); // // DESCOMENTE O BLOCO ABAIXO PARA CRIAR O DIRETÓRIO RAIZ ANTES DE RODAR O MENU // // Cria o diretório raiz do sistema. Root sempre tem permissão total "rwx" - // try { - // fileSystem.mkdir(ROOT_DIR, ROOT_USER); - // } catch (CaminhoJaExistenteException | PermissaoException e) { - // System.out.println(e.getMessage()); - // } + try { + // Cria diretório raiz com permissão total para root + fileSystem.mkdir(ROOT_DIR, ROOT_USER); + } catch (CaminhoJaExistenteException | PermissaoException e) { + System.out.println(e.getMessage()); + } // Menu interativo. menu(); @@ -101,6 +127,7 @@ public static void main(String[] args) { // Menu interativo para fins de teste. // Os testes junit não são feitos com esse menu, // mas diretamente na interface IFileSystem + public static void menu() { while (true) { System.out.println("\nComandos disponíveis:"); @@ -246,4 +273,5 @@ public static void cp() throws CaminhoNaoEncontradoException, PermissaoException fileSystem.cp(caminhoOrigem, caminhoDestino, user, recursivo); } + } diff --git a/Makefile b/Makefile index fb358c4..52b1d2d 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ clean: # Run the application with a username run: compile - $(JAVA) -cp $(BIN_DIR) $(MAIN_CLASS) -u $(USERNAME) + $(JAVA) -cp $(BIN_DIR) $(MAIN_CLASS) $(USERNAME) # Help target help: diff --git a/bin/Main.class b/bin/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..c169e70829b9abe22fe4b7894ecdf8633da322a3 GIT binary patch literal 7735 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 literal 0 HcmV?d00001 diff --git a/bin/exception/CaminhoNaoEncontradoException.class b/bin/exception/CaminhoNaoEncontradoException.class new file mode 100644 index 0000000000000000000000000000000000000000..e8bda4e1dd09a2aa94acfa9b229715c66f714d25 GIT binary patch literal 268 zcmX^0Z`VEs1_nn4UM>bE24;2!79Ivx1~x_p;jF~6ME#t^ymWonisaOSlFa-(Mg}&U z%)HDJJ4Oak4IhMp;F6-uymV{LFm?tGMh5j%n0kHZ#N5ohjC{YueAm3>{JfH)#FTs_ z(^#DIQ&Jfj_bE24;2!79Ivx1~x_p;jF~6ME#t^ymWonisaOSlFa-(Mg}&U z%)HDJJ4Oak4IhMp;F6-uymV{LFm?tGMh2Nwn0ozy)S}$X;^M@7BqLay^HWk88TfrN z^HTjvbCXhwLK2g5fFfMM`K3k4scxAdjyR@PJ&=VAiVW;Phk^hj5CWYFBsqaRC7>us goJ~u6I|JiJusj!#1bGW63RKAsRLKowGcoW00FJ#kU;qFB literal 0 HcmV?d00001 diff --git a/bin/filesys/FileSystem.class b/bin/filesys/FileSystem.class new file mode 100644 index 0000000000000000000000000000000000000000..06ef63301ec71bdb4dfc3391d7fbd465e145ad53 GIT binary patch literal 1950 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 literal 0 HcmV?d00001 diff --git a/bin/filesys/IFileSystem.class b/bin/filesys/IFileSystem.class new file mode 100644 index 0000000000000000000000000000000000000000..fe05c0bc11242b247f0f3ca919ff3aa2c1056d22 GIT binary patch literal 858 zcmbVK%T59@6g?e*5qzQe7Tp=ag|k*yYB2E;H6dZ4t2$IDGE>qi2*2jS5AdUmcTi-^ zu$ZuEdr!|fy=~9u*ZT*6Gwj*07z!`4ErLPdTwT(lItYyLY@`_SE#Bi!oBIvt{<$Sw z!;p5Ho~kq4ly1kHRimZfIGqkD*BEk@zAHLLDnGE1WjGL{+PUDK^qcCAtBUU`-)LS} ze{36b48<||L1<3~0dYrq>ezd&OHH1MIxg32EHUhlJ%1ax=9Rvrm+_5=m|NOoC?#@! z3@@5Cs_Qmse$&zjhQnmir}I#p(t^{|mlJ7zB$n4>I8G#p|6X{e)edNII}9gNx(x4~ ztE#ScMVK#&RU~IeVTv*g3^SBSAWN}JBSW=KRR$Jjkt1v#3lVH_h~=>y!G3rv6Lej;UH> permissoes) { + this.fileSystemImpl = new FileSystemImpl(permissoes); + } + public FileSystem() { - fileSystemImpl = new FileSystemImpl(); + this.fileSystemImpl = new FileSystemImpl(); + } + + // Função de add Usuário + public void addUser(String usuario) { + if (fileSystemImpl instanceof FileSystemImpl fsImpl) { + fsImpl.addUser(usuario); + } } @Override @@ -64,4 +80,5 @@ public void cp(String caminhoOrigem, String caminhoDestino, String usuario, bool throws CaminhoNaoEncontradoException, PermissaoException { fileSystemImpl.cp(caminhoOrigem, caminhoDestino, usuario, recursivo); } + } \ No newline at end of file diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index 45fa05d..62066e7 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -1,5 +1,13 @@ package filesys; +import java.util.Set; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; import exception.PermissaoException; @@ -8,63 +16,520 @@ // A classe pode ser alterada. // O construtor, argumentos do construtor podem ser modificados // e atributos & métodos privados podem ser adicionados + public final class FileSystemImpl implements IFileSystem { + private static final String ROOT_USER = "root"; // pode ser necessário + private static final String ROOT_DIR = "/"; // diretório raiz - public FileSystemImpl() {} + public Map> permissoes; - @Override - public void mkdir(String caminho, String nome) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mkdir'"); + // Função para adicionar meu usuário + private final Set usuarios = new HashSet<>(); + + // Guarda se é arquivo ou diretório + private Map isArquivo; + + // Guarda conteúdo dos arquivos + private Map conteudoArquivos; + + //public FileSystemImpl(Map> permissoes) { + //this.permissoes = permissoes; + // Inicialização dos diretórios, arquivos, etc. + //} + + public FileSystemImpl(Map> permissoes) { + this.permissoes = permissoes; + this.isArquivo = new HashMap<>(); + this.conteudoArquivos = new HashMap<>(); + + // Preenche usuários a partir das chaves do mapa permissoes + if (permissoes != null) { + for (Map usuariosPerms : permissoes.values()) { + for (String usuario : usuariosPerms.keySet()) { + if (usuario != null && !usuario.trim().isEmpty()) { + this.usuarios.add(usuario); + } + } + } + } + + // Garante que root existe e tem permissão total para raiz + if (!usuarios.contains(ROOT_USER)) { + usuarios.add(ROOT_USER); + } + + permissoes.putIfAbsent(ROOT_DIR, new HashMap<>()); + permissoes.get(ROOT_DIR).put(ROOT_USER, "rwx"); + isArquivo.put(ROOT_DIR, false); // raiz é diretório +} + + public FileSystemImpl() { + + this.permissoes = new HashMap<>(); + this.isArquivo = new HashMap<>(); + this.conteudoArquivos = new HashMap<>(); + + // Inicialização de diretórios, etc. + + // Adicionador root como usuário + addUser(ROOT_USER); + + // Inicializar raiz com permissão total para root + Map rootPerms = new HashMap<>(); + rootPerms.put(ROOT_USER, "rwx"); + permissoes.put("/", rootPerms); + isArquivo.put("/", false); // raiz é diretório + + } + + // Função para adicionar meu usuário + + public void addUser(String usuario) { + if (usuario != null && !usuario.trim().isEmpty()) { + usuarios.add(usuario); + } + } + + + private boolean usuarioExiste(String usuario) { + return usuarios.contains(usuario); + } + + // Getter às permissões + public Map> getPermissoes() { + return permissoes; + } + + // Listar os usuários + public Set getUsuarios() { + return Collections.unmodifiableSet(usuarios); } + private boolean temPermissao(String caminho, String usuario, char tipoPermissao) { + if (ROOT_USER.equals(usuario)) return true; + + // Caminho atual (parte mais específica) + String caminhoAtual = caminho; + + while (caminhoAtual != null && !caminhoAtual.isEmpty()) { + Map mapUsuarioPerm = permissoes.get(caminhoAtual); + if (mapUsuarioPerm != null && mapUsuarioPerm.containsKey(usuario)) { + String perm = mapUsuarioPerm.get(usuario); + return perm.indexOf(tipoPermissao) != -1; + } + + // Se chegou na raiz, para + if (caminhoAtual.equals("/")) break; + + // Sobe um nível no caminho + int lastSlash = caminhoAtual.lastIndexOf('/'); + caminhoAtual = lastSlash > 0 ? caminhoAtual.substring(0, lastSlash) : "/"; + } + + // Se não encontrou permissão exata, procura se tem permissão de /** no "/" + Map raizPerms = permissoes.get("/"); + if (raizPerms != null && raizPerms.containsKey(usuario)) { + String perm = raizPerms.get(usuario); + return perm.indexOf(tipoPermissao) != -1; + } + + return false; + } + + @Override + public void mkdir(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { + + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + + if (caminho == null || caminho.isEmpty() || !caminho.startsWith("/")) { + throw new IllegalArgumentException("Caminho inválido."); + } + + if (permissoes.containsKey(caminho)) { + throw new CaminhoJaExistenteException("O diretório já existe: " + caminho); + } + + int lastSlashIndex = caminho.lastIndexOf('/'); + String caminhoPai = (lastSlashIndex == 0) ? "/" : caminho.substring(0, lastSlashIndex); + + if (!permissoes.containsKey(caminhoPai)) { + throw new PermissaoException("Diretório pai inexistente: " + caminhoPai); + } + + Map permsPai = permissoes.get(caminhoPai); + String permUsuario = ROOT_USER.equals(usuario) ? "rwx" : permsPai.get(usuario); + if (permUsuario == null || !permUsuario.contains("w")) { + throw new PermissaoException("Usuário não tem permissão de escrita no diretório pai."); + } + + Map novasPerms = new HashMap<>(); + novasPerms.put(usuario, "rwx"); + novasPerms.put(ROOT_USER, "rwx"); + + permissoes.put(caminho, novasPerms); + isArquivo.put(caminho, false); // <-- ESSENCIAL PARA O MÉTODO rm FUNCIONAR + + System.out.println("Diretório criado com sucesso: " + caminho); +} + @Override public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'chmod'"); + // throw new UnsupportedOperationException("Método não implementado 'chmod'"); + + // Verifica se o caminho existe (permissoes contem o caminho) + if (!permissoes.containsKey(caminho)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + + // Verfica se o usuário que está tentando alterar é root ou tem permissão rwx + if (!ROOT_USER.equals(usuario)) { + + Map permissoesDoCaminho = permissoes.get(caminho); + String permUsuario = permissoesDoCaminho.get(usuario); + + if (permUsuario == null || ! permUsuario.startsWith("rw")) { + throw new PermissaoException("Usuário " + usuario + " não tem permissão para alterar permissões em " + caminho); + } + } + + // Verificar se o usuarioAlvo existe + if (!usuarioExiste(usuarioAlvo)) { + throw new PermissaoException("Usuário alvo não existe: " + usuarioAlvo); + } + + // Atualiza a permissão para o usuarioAlvo no caminho + Map permissoesDoCaminho = permissoes.get(caminho); + permissoesDoCaminho.put(usuarioAlvo, permissao); + + // imprimir a mudança de permissão + System.out.println("Permissão para " + usuarioAlvo + " no caminho " + caminho + " alterada para " + permissao); + } @Override - public void rm(String caminho, String usuario, boolean recursivo) - throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'rm'"); + public void rm(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + + if (!permissoes.containsKey(caminho)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + + Map perms = permissoes.get(caminho); + String permUsuario = ROOT_USER.equals(usuario) ? "rwx" : perms.get(usuario); + if (permUsuario == null || !permUsuario.contains("w")) { + throw new PermissaoException("Usuário não tem permissão de escrita para remover: " + caminho); + } + + // Se for diretório e não recursivo, deve falhar se tiver conteúdo + if (!isArquivo.get(caminho) && !recursivo) { + // Verifica se existe algum caminho que começa com esse caminho + "/" + for (String c : permissoes.keySet()) { + if (!c.equals(caminho) && c.startsWith(caminho.endsWith("/") ? caminho : caminho + "/")) { + throw new PermissaoException("Diretório não está vazio e recursivo não foi especificado."); + } + } + } + + // Remove recursivamente todos os caminhos filhos + permissoes.keySet().removeIf(c -> c.equals(caminho) || c.startsWith(caminho.endsWith("/") ? caminho : caminho + "/")); + isArquivo.keySet().removeIf(c -> c.equals(caminho) || c.startsWith(caminho.endsWith("/") ? caminho : caminho + "/")); + conteudoArquivos.keySet().removeIf(c -> c.equals(caminho) || c.startsWith(caminho.endsWith("/") ? caminho : caminho + "/")); + + System.out.println("Removido: " + caminho); } @Override public void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'touch'"); + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + + if (caminho == null || caminho.isEmpty() || !caminho.startsWith("/")) { + throw new IllegalArgumentException("Caminho inválido."); + } + + if (permissoes.containsKey(caminho)) { + throw new CaminhoJaExistenteException("O arquivo já existe: " + caminho); + } + + int lastSlashIndex = caminho.lastIndexOf('/'); + String caminhoPai = (lastSlashIndex == 0) ? "/" : caminho.substring(0, lastSlashIndex); + + if (!permissoes.containsKey(caminhoPai)) { + throw new PermissaoException("Diretório pai inexistente: " + caminhoPai); + } + + Map permsPai = permissoes.get(caminhoPai); + String permUsuario = ROOT_USER.equals(usuario) ? "rwx" : permsPai.get(usuario); + if (permUsuario == null || !permUsuario.contains("w")) { + throw new PermissaoException("Usuário não tem permissão de escrita no diretório pai."); + } + + Map novasPerms = new HashMap<>(); + novasPerms.put(usuario, "rw"); // Para arquivos, geralmente "rw" + novasPerms.put(ROOT_USER, "rw"); + + permissoes.put(caminho, novasPerms); + isArquivo.put(caminho, true); + conteudoArquivos.put(caminho, new byte[0]); // Arquivo vazio + + System.out.println("Arquivo criado com sucesso: " + caminho); } + @Override public void write(String caminho, String usuario, boolean anexar, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'write'"); + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + if (!permissoes.containsKey(caminho)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + if (!Boolean.TRUE.equals(isArquivo.get(caminho))) { + throw new PermissaoException("O caminho não é um arquivo: " + caminho); + } + Map perms = permissoes.get(caminho); + String permUsuario = ROOT_USER.equals(usuario) ? "rw" : perms.get(usuario); + if (permUsuario == null || !permUsuario.contains("w")) { + throw new PermissaoException("Usuário não tem permissão para escrever no arquivo: " + caminho); + } + + // Bloco de escrita + final int BLOCK_SIZE = 256; + byte[] conteudoAtual = conteudoArquivos.get(caminho); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + + try { + if (anexar) { + output.write(conteudoAtual); + } + + int offset = 0; + while (offset < buffer.length) { + int blockLen = Math.min(BLOCK_SIZE, buffer.length - offset); + output.write(buffer, offset, blockLen); + offset += blockLen; + } + + conteudoArquivos.put(caminho, output.toByteArray()); + System.out.println("Escrita por blocos concluída: " + caminho); + } catch (IOException e) { + e.printStackTrace(); // Não deve ocorrer em ByteArrayOutputStream + } } @Override public void read(String caminho, String usuario, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'read'"); + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + if (!permissoes.containsKey(caminho)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + if (!Boolean.TRUE.equals(isArquivo.get(caminho))) { + throw new PermissaoException("O caminho não é um arquivo: " + caminho); + } + + Map perms = permissoes.get(caminho); + String permUsuario = ROOT_USER.equals(usuario) ? "rw" : perms.get(usuario); + if (permUsuario == null || !permUsuario.contains("r")) { + throw new PermissaoException("Usuário não tem permissão de leitura no arquivo: " + caminho); + } + + byte[] conteudo = conteudoArquivos.get(caminho); + + // Leitura em blocos + final int BLOCK_SIZE = 256; + int offset = 0; + while (offset < conteudo.length && offset < buffer.length) { + int blockLen = Math.min(BLOCK_SIZE, conteudo.length - offset); + System.arraycopy(conteudo, offset, buffer, offset, blockLen); + offset += blockLen; + } + + String conteudoStr = new String(buffer).trim(); + System.out.println("Conteúdo lido por blocos:"); + System.out.println(conteudoStr); } @Override public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mv'"); + + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + if (!permissoes.containsKey(caminhoAntigo)) { + throw new CaminhoNaoEncontradoException("Caminho antigo não encontrado: " + caminhoAntigo); + } + + // Verificar permissão de escrita no diretório pai do caminhoAntigo + int lastSlashOld = caminhoAntigo.lastIndexOf('/'); + String paiAntigo = (lastSlashOld == 0) ? "/" : caminhoAntigo.substring(0, lastSlashOld); + Map permsPaiAntigo = permissoes.get(paiAntigo); + String permUsuarioAntigo = ROOT_USER.equals(usuario) ? "rwx" : permsPaiAntigo.get(usuario); + if (permUsuarioAntigo == null || !permUsuarioAntigo.contains("w")) { + throw new PermissaoException("Usuário não tem permissão de escrita no diretório pai do caminho antigo."); + } + + // Se já existe como destino, não precisa verificar o pai + if (!permissoes.containsKey(caminhoNovo)) { + // Se não existe, verificar o pai + int lastSlashNew = caminhoNovo.lastIndexOf('/'); + String paiNovo = (lastSlashNew == 0) ? "/" : caminhoNovo.substring(0, lastSlashNew); + if (!permissoes.containsKey(paiNovo)) { + throw new PermissaoException("Diretório pai do caminho novo não existe: " + paiNovo); + } + Map permsPaiNovo = permissoes.get(paiNovo); + String permUsuarioNovo = ROOT_USER.equals(usuario) ? "rwx" : permsPaiNovo.get(usuario); + if (permUsuarioNovo == null || !permUsuarioNovo.contains("w")) { + throw new PermissaoException("Usuário não tem permissão de escrita no diretório pai do caminho novo."); + } + } + + // Lista de caminhos que serão movidos (inclui caminhoAntigo e seus filhos) + Set caminhosAMover = new HashSet<>(); + String prefixoAntigo = caminhoAntigo.endsWith("/") ? caminhoAntigo : caminhoAntigo + "/"; + for (String c : permissoes.keySet()) { + if (c.equals(caminhoAntigo) || c.startsWith(prefixoAntigo)) { + caminhosAMover.add(c); + } + } + + // Mover: remover entradas antigas e criar novas com o prefixo atualizado + for (String c : caminhosAMover) { + String novoCaminho = caminhoNovo + c.substring(caminhoAntigo.length()); + + // Permissões + Map p = permissoes.remove(c); + permissoes.put(novoCaminho, p); + + // isArquivo + Boolean isA = isArquivo.remove(c); + isArquivo.put(novoCaminho, isA); + + // Conteúdo arquivos + if (isA) { + byte[] conteudo = conteudoArquivos.remove(c); + conteudoArquivos.put(novoCaminho, conteudo); + } + } } @Override public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'ls'"); + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + if (!permissoes.containsKey(caminho)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + + // Verifica permissão de leitura + Map perms = permissoes.get(caminho); + String permUsuario = ROOT_USER.equals(usuario) ? "r" : perms.get(usuario); + if (permUsuario == null || !permUsuario.contains("r")) { + throw new PermissaoException("Usuário não tem permissão para listar: " + caminho); + } + + for (String c : permissoes.keySet()) { + if (c.equals(caminho)) continue; + if (c.startsWith(caminho.endsWith("/") ? caminho : caminho + "/")) { + if (!recursivo) { + // Lista só filhos diretos + String restante = c.substring(caminho.length()); + if (restante.startsWith("/")) { + restante = restante.substring(1); + } + if (!restante.contains("/")) { + System.out.println(c); + } + } else { + System.out.println(c); + } + } + } } + @Override public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'cp'"); - } - public void addUser(String user) { - throw new UnsupportedOperationException("Método não implementado 'addUser'"); + if (!usuarioExiste(usuario)) { + throw new PermissaoException("Usuário não fornecido ou inexistente."); + } + if (!permissoes.containsKey(caminhoOrigem)) { + throw new CaminhoNaoEncontradoException("Caminho origem não encontrado: " + caminhoOrigem); + } + + // Verifica permissão leitura no caminhoOrigem + Map permsOrigem = permissoes.get(caminhoOrigem); + String permUsuarioOrigem = ROOT_USER.equals(usuario) ? "rwx" : permsOrigem.get(usuario); + if (permUsuarioOrigem == null || !permUsuarioOrigem.contains("r")) { + throw new PermissaoException("Usuário não tem permissão para ler o caminho origem."); + } + + // Verifica permissão escrita no diretório pai do destino + if (!permissoes.containsKey(caminhoDestino)) { + throw new PermissaoException("Diretório de destino não existe: " + caminhoDestino); + } + Map permsDestino = permissoes.get(caminhoDestino); + String permUsuarioDestino = ROOT_USER.equals(usuario) ? "rwx" : permsDestino.get(usuario); + if (permUsuarioDestino == null || !permUsuarioDestino.contains("w")) { + throw new PermissaoException("Usuário não tem permissão para escrever no destino."); + } + if (permUsuarioDestino == null || !permUsuarioDestino.contains("w")) { + throw new PermissaoException("Usuário não tem permissão para escrever no diretório pai do destino."); + } + + boolean origemArquivo = Boolean.TRUE.equals(isArquivo.get(caminhoOrigem)); + + if (!origemArquivo && !recursivo) { + throw new PermissaoException("Caminho origem e diretório recursivo não foi especificado."); + } + + // Caminhos a copiar (origem + filhos se diretório) + Set caminhosACopiar = new HashSet<>(); + if (origemArquivo) { + caminhosACopiar.add(caminhoOrigem); + } else { + String prefixoOrigem = caminhoOrigem.endsWith("/") ? caminhoOrigem : caminhoOrigem + "/"; + for (String c : permissoes.keySet()) { + if (c.equals(caminhoOrigem) || c.startsWith(prefixoOrigem)) { + caminhosACopiar.add(c); + } + } + } + + for (String c : caminhosACopiar) { + String novoCaminho = caminhoDestino + c.substring(caminhoOrigem.length()); + + // Clonar permissões + Map permsOrig = permissoes.get(c); + Map novaPerms = new HashMap<>(permsOrig); + permissoes.put(novoCaminho, novaPerms); + + // Clonar isArquivo + Boolean isA = isArquivo.get(c); + isArquivo.put(novoCaminho, isA); + + // Clonar conteúdo se arquivo + if (isA) { + byte[] conteudo = conteudoArquivos.get(c); + conteudoArquivos.put(novoCaminho, conteudo.clone()); + } + } } + } + + diff --git a/filesys/IFileSystem.java b/filesys/IFileSystem.java index a0f0ce0..317323f 100644 --- a/filesys/IFileSystem.java +++ b/filesys/IFileSystem.java @@ -44,4 +44,5 @@ public interface IFileSystem { // Copia um arquivo ou diretório. Se o diretório não existir, será lançada uma exceção. void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException; + } \ No newline at end of file diff --git a/tests/PermissionTest.java b/tests/PermissionTest.java index 6026e31..2ea0ec3 100644 --- a/tests/PermissionTest.java +++ b/tests/PermissionTest.java @@ -1,26 +1,286 @@ package tests; import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.Test; + +import exception.CaminhoJaExistenteException; +import exception.CaminhoNaoEncontradoException; +import exception.PermissaoException; + import org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import filesys.FileSystemImpl; import filesys.IFileSystem; +import filesys.FileSystem; // Essa classe testa cenários de permissão + public class PermissionTest { - private static IFileSystem fileSystem; - @BeforeAll - public static void setUp() { - fileSystem = new FileSystemImpl(/*args...*/); + private FileSystemImpl fs; + + @BeforeEach + public void setup() { + fs = new FileSystemImpl(); + fs.addUser("alice"); + fs.addUser("bob"); + // Cria estrutura básica para testes + try { + fs.mkdir("/dir", "root"); + fs.touch("/dir/file.txt", "root"); + fs.mkdir("/dir/subdir", "root"); + // Define permissões para os usuários + fs.permissoes.get("/dir").put("alice", "rwx"); + fs.permissoes.get("/dir/file.txt").put("alice", "rw"); + fs.permissoes.get("/dir/subdir").put("alice", "rwx"); + fs.permissoes.get("/dir").put("bob", "r"); + fs.permissoes.get("/dir/file.txt").put("bob", "r"); + } catch (Exception e) { + fail("Setup falhou: " + e.getMessage()); + } + } + + @Test + public void testAddUser_andUsuarioExiste() { + assertTrue(fs.getPermissoes().containsKey("/")); + // Usuário root já existe por padrão + fs.addUser("charlie"); + // Não há método direto para checar usuário, mas mkdir lança PermissaoException para usuário inválido + assertThrows(PermissaoException.class, () -> fs.mkdir("/dirInvalidUser", "invalidUser")); + } + + @Test + public void testMkdirDiretorioPaiNaoExiste() { + Exception ex = assertThrows(PermissaoException.class, () -> fs.mkdir("/noParent/dir", "root")); + assertTrue(ex.getMessage().contains("Diretório pai inexistente")); + } + + @Test + public void testMkdirCaminhoJaExistente() throws Exception { + fs.mkdir("/dirExistente", "root"); + assertThrows(CaminhoJaExistenteException.class, () -> fs.mkdir("/dirExistente", "root")); + } + + @Test + public void testMkdirSemPermissao() { + fs.addUser("carol"); + Exception ex = assertThrows(PermissaoException.class, () -> fs.mkdir("/dir2", "carol")); + assertTrue(ex.getMessage().contains("Usuário não tem permissão de escrita")); + } + + @Test + public void testChmodSucesso() throws Exception { + fs.mkdir("/dirChmod", "root"); + fs.addUser("user1"); + fs.getPermissoes().get("/dirChmod").put("root", "rwx"); + fs.getPermissoes().get("/dirChmod").put("user2", "rw"); + fs.addUser("user2"); + // root pode alterar + fs.chmod("/dirChmod", "root", "user1", "rwx"); + assertEquals("rwx", fs.getPermissoes().get("/dirChmod").get("user1")); + } + + @Test + public void testChmodUsuarioNaoTemPermissao() throws Exception { + fs.mkdir("/dirChmod2", "root"); + fs.addUser("user3"); + fs.getPermissoes().get("/dirChmod2").put("user3", "r"); + fs.addUser("user4"); + Exception ex = assertThrows(PermissaoException.class, () -> fs.chmod("/dirChmod2", "user3", "user4", "rw")); + assertTrue(ex.getMessage().contains("não tem permissão")); + } + + @Test + public void testChmodCaminhoNaoEncontrado() { + assertThrows(CaminhoNaoEncontradoException.class, + () -> fs.chmod("/noExist", "root", "user1", "rw")); + } + + @Test + public void testTouchSucesso() throws Exception { + fs.mkdir("/dirTouch", "root"); + fs.touch("/dirTouch/fileTouch", "root"); + assertTrue(fs.getPermissoes().containsKey("/dirTouch/fileTouch")); + } + + @Test + public void testTouchCaminhoJaExistente() throws Exception { + fs.mkdir("/dirTouch2", "root"); + fs.touch("/dirTouch2/fileTouch2", "root"); + assertThrows(CaminhoJaExistenteException.class, + () -> fs.touch("/dirTouch2/fileTouch2", "root")); + } + + @Test + public void testWriteReadSucesso() throws Exception { + fs.mkdir("/dirWriteRead", "root"); + fs.touch("/dirWriteRead/fileWriteRead", "root"); + byte[] data = "hello".getBytes(); + fs.write("/dirWriteRead/fileWriteRead", "root", false, data); + byte[] buffer = new byte[10]; + fs.read("/dirWriteRead/fileWriteRead", "root", buffer); + String result = new String(buffer, 0, data.length); + assertEquals("hello", result); + } + + @Test + public void testWritePermissaoNegada() throws Exception { + fs.mkdir("/dirWrite2", "root"); + fs.touch("/dirWrite2/fileWrite2", "root"); + fs.addUser("dave"); + Exception ex = assertThrows(PermissaoException.class, () -> fs.write("/dirWrite2/fileWrite2", "dave", false, "data".getBytes())); + assertTrue(ex.getMessage().contains("não tem permissão")); + } + + @Test + public void testReadPermissaoNegada() throws Exception { + fs.mkdir("/dirRead2", "root"); + fs.touch("/dirRead2/fileRead2", "root"); + fs.addUser("eve"); + Exception ex = assertThrows(PermissaoException.class, () -> fs.read("/dirRead2/fileRead2", "eve", new byte[10])); + assertTrue(ex.getMessage().contains("não tem permissão")); + } + + @Test + public void testMvSucesso() throws Exception { + fs.mkdir("/dirMv", "root"); + fs.touch("/dirMv/fileMv", "root"); + fs.mkdir("/dirDest", "root"); + fs.mv("/dirMv/fileMv", "/dirDest/fileMvNew", "root"); + assertFalse(fs.getPermissoes().containsKey("/dirMv/fileMv")); + assertTrue(fs.getPermissoes().containsKey("/dirDest/fileMvNew")); + } + + @Test + public void testMvPermissaoNegada() throws Exception { + fs.mkdir("/dirMv2", "root"); + fs.touch("/dirMv2/fileMv2", "root"); + fs.mkdir("/dirDest2", "root"); + fs.addUser("frank"); + Exception ex = assertThrows(PermissaoException.class, () -> fs.mv("/dirMv2/fileMv2", "/dirDest2/fileMv2New", "frank")); + assertTrue(ex.getMessage().contains("não tem permissão")); + } + + @Test + public void testMvCaminhoAntigoNaoExiste() { + assertThrows(CaminhoNaoEncontradoException.class, + () -> fs.mv("/noOldPath/file", "/someNewPath/file", "root")); + } + + @Test + public void testMvDiretorioPaiNovoNaoExiste() throws Exception { + fs.mkdir("/dirMv3", "root"); + fs.touch("/dirMv3/fileMv3", "root"); + Exception ex = assertThrows(PermissaoException.class, + () -> fs.mv("/dirMv3/fileMv3", "/noParentDir/fileNew", "root")); + assertTrue(ex.getMessage().contains("Diretório pai do caminho novo não existe")); + } + + @Test + public void testLs_SucessoNaoRecursivo() throws Exception { + assertDoesNotThrow(() -> fs.ls("/dir", "alice", false)); + } + + @Test + public void testLs_SucessoRecursivo() throws Exception { + assertDoesNotThrow(() -> fs.ls("/dir", "alice", true)); + } + + @Test + public void testLs_CaminhoNaoEncontrado() { + Exception ex = assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls("/inexistente", "alice", false)); + assertTrue(ex.getMessage().contains("Caminho não encontrado")); + } + + // ------------------- TESTES CP ------------------- + + @Test + public void testCp_ArquivoSucesso() throws Exception { + fs.cp("/dir/file.txt", "/dir/file_copia.txt", "alice", false); + assertTrue(fs.permissoes.containsKey("/dir/file_copia.txt")); + } + + @Test + public void testCp_CaminhoOrigemNaoEncontrado() { + Exception ex = assertThrows(CaminhoNaoEncontradoException.class, + () -> fs.cp("/dir/inexistente.txt", "/dir/file_copia.txt", "alice", false)); + assertTrue(ex.getMessage().contains("origem não encontrado")); } @Test - public void testPermission() { - // Teste de permissão - assertTrue(true); + public void testCp_SemPermissaoLeituraOrigem() { + fs.permissoes.get("/dir/file.txt").put("bob", ""); // sem permissão leitura + Exception ex = assertThrows(PermissaoException.class, + () -> fs.cp("/dir/file.txt", "/dir/file_copia.txt", "bob", false)); + assertTrue(ex.getMessage().contains("não tem permissão para ler")); } + + @Test + public void testCp_SemPermissaoEscritaDestino() { + fs.permissoes.get("/dir").put("bob", "r"); // só leitura, sem escrita + Exception ex = assertThrows(PermissaoException.class, + () -> fs.cp("/dir/file.txt", "/dir/file_copia.txt", "bob", false)); + assertTrue(ex.getMessage().contains("não tem permissão para escrever")); + } + + @Test + public void testRead_ArquivoSucesso() throws Exception { + byte[] buffer = new byte[10]; + fs.read("/dir/file.txt", "alice", buffer); + // Se não lançar exceção, sucesso + } + + @Test + public void testRead_CaminhoNaoEncontrado() { + byte[] buffer = new byte[10]; + Exception ex = assertThrows(CaminhoNaoEncontradoException.class, + () -> fs.read("/dir/inexistente.txt", "alice", buffer)); + assertTrue(ex.getMessage().contains("não encontrado")); + } + + @Test + public void testRead_CaminhoNaoArquivo() throws Exception { + fs.mkdir("/dir/subdir2", "alice"); + byte[] buffer = new byte[10]; + Exception ex = assertThrows(PermissaoException.class, + () -> fs.read("/dir/subdir2", "alice", buffer)); + assertTrue(ex.getMessage().contains("não é um arquivo")); + } + + @Test + public void testRm_ArquivoSucesso() throws Exception { + fs.touch("/dir/file_para_remover.txt", "alice"); + fs.rm("/dir/file_para_remover.txt", "alice", false); + assertFalse(fs.permissoes.containsKey("/dir/file_para_remover.txt")); + } + + @Test + public void testRm_SemPermissao() throws Exception { + fs.touch("/dir/file_para_remover.txt", "alice"); + fs.permissoes.get("/dir/file_para_remover.txt").put("bob", "r"); // só leitura + Exception ex = assertThrows(PermissaoException.class, + () -> fs.rm("/dir/file_para_remover.txt", "bob", false)); + assertTrue(ex.getMessage().contains("não tem permissão de escrita")); + } + + @Test + public void testRm_CaminhoNaoEncontrado() { + Exception ex = assertThrows(CaminhoNaoEncontradoException.class, + () -> fs.rm("/inexistente", "alice", false)); + assertTrue(ex.getMessage().contains("não encontrado")); + } + } + + diff --git a/users/users b/users/users index 58c2992..d86e641 100644 --- a/users/users +++ b/users/users @@ -4,4 +4,12 @@ joao /** rw- pedro /** rw- tiago /** rw- luzia /** rwx -carla /** r-- \ No newline at end of file +carla /** r-- +diogo /usr/bin/diogo rw- +frieren /usr/bin/frieren rw- +bocchi /home rw- +peep /usr/include/benztruck rwx +platao /boot r-- +gawrgura /usr/bin/gooba rwx +pikachu /tmp rw- +flamengo /usr/bin/arrasca rwx