diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..698c64c1f67522450b662d8a429ecbe618bb434e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,5 @@
+FROM alpine-java:base
+MAINTAINER gltron
+COPY mozen/target/mozen-0.0.1-SNAPSHOT.jar /home/mozen-0.0.1-SNAPSHOT.jar
+CMD ["java","-jar","/home/mozen-0.0.1-SNAPSHOT.jar"]
+EXPOSE 8181
\ No newline at end of file
diff --git a/buildAndRun.sh b/buildAndRun.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c40d0ae3c319daf33e0cf5b13b5b8cf6b3952d8c
--- /dev/null
+++ b/buildAndRun.sh
@@ -0,0 +1,2 @@
+docker build . -t gltron/mozen
+docker run -d -p 8007:8181 gltron/mozen
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/auth/WebSecurity.java b/mozen/src/main/java/mozen/auth/WebSecurity.java
index 259f5e869185701a10bd26243d075b0da0474187..991752b2455fd291c68f95b396aa269f05f53e56 100644
--- a/mozen/src/main/java/mozen/auth/WebSecurity.java
+++ b/mozen/src/main/java/mozen/auth/WebSecurity.java
@@ -35,15 +35,14 @@ public class WebSecurity extends WebSecurityConfigurerAdapter{
     .and()
       .authorizeRequests() 
         .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
+        .antMatchers(HttpMethod.POST, "/login").permitAll()
         .antMatchers(HttpMethod.POST, "/user/signup").permitAll()
         .antMatchers(HttpMethod.GET, "/search").permitAll()
         .antMatchers(HttpMethod.GET, "/models").permitAll()
         .antMatchers(HttpMethod.GET, "/models/tags").permitAll()
         .antMatchers(HttpMethod.GET, "/models/download").permitAll()
         .antMatchers(HttpMethod.GET, "/models/downloadLayer").permitAll()
-        .antMatchers(HttpMethod.GET, "/user/list").hasRole("ADMIN")
-        .antMatchers(HttpMethod.GET, "/model/list").hasRole("ADMIN")
-        .anyRequest().authenticated()
+        // .anyRequest().authenticated()
     .and()
       .addFilter(new JwtAuthenticationFilter(authenticationManager()))
       .addFilter(new JwtAuthorizationFilter(authenticationManager()))
diff --git a/mozen/src/main/java/mozen/business/IModelManager.java b/mozen/src/main/java/mozen/business/IModelManager.java
index 1823817ecf5170f0717a6a522271782d360725b5..348eeb61399c3b85f572bce62a0554b8e25dff20 100644
--- a/mozen/src/main/java/mozen/business/IModelManager.java
+++ b/mozen/src/main/java/mozen/business/IModelManager.java
@@ -9,6 +9,7 @@ import mozen.messages.TagMessage;
 import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.messages.SearchResult;
+import mozen.messages.TagCategoryMessage;
 import mozen.model.TagCategory;
 import mozen.model.User;
 
@@ -22,6 +23,10 @@ public interface IModelManager {
   void removeLayer(long id, User user) throws Exception;
 
   void addTag(TagMessage message);
+  void removeTag(long id);
+
+  void addCategory(TagCategoryMessage message);
+  void removeCategory(long id);
 
   Model getModel(long id);
   Collection<Model> getModels();
diff --git a/mozen/src/main/java/mozen/business/ModelManager.java b/mozen/src/main/java/mozen/business/ModelManager.java
index 48897ec71672fc9d685b668db7a9f2dff17b94f8..251404cf1438157833df9d39b120addeacb928b6 100644
--- a/mozen/src/main/java/mozen/business/ModelManager.java
+++ b/mozen/src/main/java/mozen/business/ModelManager.java
@@ -19,6 +19,7 @@ import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.model.Role;
 import mozen.messages.SearchResult;
+import mozen.messages.TagCategoryMessage;
 import mozen.model.Tag;
 import mozen.model.TagCategory;
 import mozen.model.User;
@@ -42,7 +43,8 @@ public class ModelManager implements IModelManager {
   public Long addModel(ModelMessage message, User user) throws Exception {
     Model model = new Model();
 
-    System.err.println("[MODEL MANAGER] add model n:"+message.getName()+" sd:"+message.getShortDescription()+" ld:"+message.getLongDescription()+" t:"+message.getTags()+" l:"+message.getCustomLayers());
+    System.err.println("[MODEL MANAGER] add model n:" + message.getName() + " sd:" + message.getShortDescription()
+        + " ld:" + message.getLongDescription() + " t:" + message.getTags() + " l:" + message.getCustomLayers());
 
     model.setName(message.getName());
     model.setShortDescription(message.getShortDescription());
@@ -55,7 +57,7 @@ public class ModelManager implements IModelManager {
         tags.add(tag);
       }
       model.setTags(tags);
-    } 
+    }
 
     model.setVotes(0);
     model.setAdded(new Date());
@@ -65,9 +67,9 @@ public class ModelManager implements IModelManager {
     try {
       modelRepo.save(model);
     } catch (Exception e) {
-      System.err.println("[MODEL MANAGER] Add model error "+e.getMessage());
+      System.err.println("[MODEL MANAGER] Add model error " + e.getMessage());
     }
-    
+
     return model.getId();
   }
 
@@ -119,17 +121,17 @@ public class ModelManager implements IModelManager {
 
   @Override
   public SearchResult findModel(String name, int page, int size, String sort) {
-    System.err.println("[MODEL MANAGER] search n:"+name+" p:"+page+" si:"+size+" so:"+sort);
-    Pageable paging = PageRequest.of(page-1, size, Sort.by(sort));
+    System.err.println("[MODEL MANAGER] search n:" + name + " p:" + page + " si:" + size + " so:" + sort);
+    Pageable paging = PageRequest.of(page - 1, size, Sort.by(sort));
     Page<Model> resultPage = modelRepo.findByNameContainingIgnoreCase(name, paging);
 
-    System.err.println("[MODEL MANAGER] search result "+resultPage.getTotalElements());
+    System.err.println("[MODEL MANAGER] search result " + resultPage.getTotalElements());
 
     SearchResult result = new SearchResult();
     if (resultPage.hasContent()) {
       result.setTotalResult((int) resultPage.getTotalElements());
       result.setTotalPage((int) resultPage.getTotalPages());
-      result.setPage(resultPage.getNumber()+1);
+      result.setPage(resultPage.getNumber() + 1);
       result.setModels(resultPage.getContent());
     } else {
       result.setPage(0);
@@ -173,7 +175,7 @@ public class ModelManager implements IModelManager {
 
   @Override
   public void addTag(TagMessage message) {
-    System.err.println("[MODEL MANAGER] add tag n:"+message.getName()+" c:"+message.getCategoryId());
+    System.err.println("[MODEL MANAGER] add tag n:" + message.getName() + " c:" + message.getCategoryId());
     Long categoryId = message.getCategoryId();
     TagCategory category = tagCategoryRepo.findById(categoryId).get();
 
@@ -190,29 +192,32 @@ public class ModelManager implements IModelManager {
   }
 
   private boolean isLayerAuthor(CustomLayer layer, User user) {
-    if (user.getRole() == Role.ROLE_ADMIN) return true;
+    if (user.getRole() == Role.ROLE_ADMIN)
+      return true;
     return layer.getModel().getAuthor() == user;
   }
 
   private boolean isModelAuthor(Model model, User user) {
-    if (user.getRole() == Role.ROLE_ADMIN) return true;
+    if (user.getRole() == Role.ROLE_ADMIN)
+      return true;
     return model.getAuthor() == user;
   }
 
   @Override
   public SearchResult findModelWithTags(String name, int page, int size, String sort, Collection<String> tagsName) {
-    System.err.println("[MODEL MANAGER] search with tags n:"+name+" p:"+page+" si:"+size+" so:"+sort+" t:"+tagsName);
-    Pageable paging = PageRequest.of(page-1, size, Sort.by(sort));
+    System.err.println(
+        "[MODEL MANAGER] search with tags n:" + name + " p:" + page + " si:" + size + " so:" + sort + " t:" + tagsName);
+    Pageable paging = PageRequest.of(page - 1, size, Sort.by(sort));
     Collection<Tag> tags = tagRepo.findByNameIn(tagsName);
-    Page<Model> resultPage = modelRepo.findByNameContainingIgnoreCaseAndTagsIn(name, tags, paging);
+    Page<Model> resultPage = modelRepo.findDistinctByNameContainingIgnoreCaseAndTagsIn(name, tags, paging);
 
-    System.err.println("[MODEL MANAGER] search result "+resultPage.getTotalElements());
+    System.err.println("[MODEL MANAGER] search result " + resultPage.getTotalElements());
 
     SearchResult result = new SearchResult();
     if (resultPage.hasContent()) {
       result.setTotalResult((int) resultPage.getTotalElements());
       result.setTotalPage((int) resultPage.getTotalPages());
-      result.setPage(resultPage.getNumber()+1);
+      result.setPage(resultPage.getNumber() + 1);
       result.setModels(resultPage.getContent());
     } else {
       result.setPage(0);
@@ -232,4 +237,21 @@ public class ModelManager implements IModelManager {
     return layerRepo.findById(id).get();
   }
 
+  @Override
+  public void removeTag(long id) {
+    tagRepo.deleteById(id);
+  }
+
+  @Override
+  public void removeCategory(long id) {
+    tagCategoryRepo.deleteById(id);
+  }
+
+  @Override
+  public void addCategory(TagCategoryMessage message) {
+    TagCategory category = new TagCategory();
+    category.setName(message.getName());
+    tagCategoryRepo.save(category);
+  }
+
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/ModelRepository.java b/mozen/src/main/java/mozen/business/ModelRepository.java
index 649ecb322c2ae0f9281381d2fba9f0d9933ed616..d8bff04ed7f471be5d9a24dc61d44cf4275687c6 100644
--- a/mozen/src/main/java/mozen/business/ModelRepository.java
+++ b/mozen/src/main/java/mozen/business/ModelRepository.java
@@ -13,7 +13,7 @@ public interface ModelRepository extends PagingAndSortingRepository<Model, Long>
   Collection<Model> findAll();
   Page<Model> findByNameContainingIgnoreCase(String name, Pageable pageable);
 
-  Page<Model> findByNameContainingIgnoreCaseAndTagsIn(String name, Collection<Tag> tags, Pageable pageable);
+  Page<Model> findDistinctByNameContainingIgnoreCaseAndTagsIn(String name, Collection<Tag> tags, Pageable pageable);
 
   // @Query("SELECT m FROM Model m WHERE m.name LIKE :name AND m.tags CONTAINS (SELECT t FROM Tag WHERE t.name IN :tags)") <- enfer absolu
   // Page<Model> findByNameContainingIgnoreCaseTags(@Param("name") String name, @Param("tags") Collection<String> tags, Pageable pageable);
diff --git a/mozen/src/main/java/mozen/messages/TagCategoryMessage.java b/mozen/src/main/java/mozen/messages/TagCategoryMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cf13ff2064f2e2c6f4df106c400530f82471944
--- /dev/null
+++ b/mozen/src/main/java/mozen/messages/TagCategoryMessage.java
@@ -0,0 +1,24 @@
+package mozen.messages;
+
+import java.io.Serializable;
+
+public class TagCategoryMessage implements Serializable{
+  private static final long serialVersionUID = 1L;
+  
+  private String name;
+
+  public TagCategoryMessage() {
+  }
+
+  public TagCategoryMessage(String name) {
+    this.name = name;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/utils/DatabaseFiller.java b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
index 75e0b15665fc05a8565e28099ff7d8da82b25b75..e556a2363c19c1bbb3592bd35a2b9a5a2a78a9fa 100644
--- a/mozen/src/main/java/mozen/utils/DatabaseFiller.java
+++ b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
@@ -1,9 +1,8 @@
 package mozen.utils;
 
 import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
@@ -11,6 +10,8 @@ import java.util.Set;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.EventListener;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -42,7 +43,7 @@ public class DatabaseFiller {
 
   @Transactional
   public void fillDB() {
-    System.err.println("FILLING DB");
+    System.err.println("[DB FILLER] Begin");
     User u1 = new User();
     u1.setEmail("user1@email.com");
     u1.setPassword(bCryptPasswordEncoder.encode("1234"));
@@ -69,7 +70,7 @@ public class DatabaseFiller {
     m1.setVotes(0);
     m1.setAdded(new Date());
     m1.setLastModified(new Date());
-    m1.setTags(tagLoader("tags.txt"));
+    m1.setTags(tagLoader());
 
     Set<CustomLayer> m1layers = new HashSet<CustomLayer>();
     CustomLayer l1 = new CustomLayer();
@@ -86,17 +87,19 @@ public class DatabaseFiller {
     userRepo.save(u2);
     userRepo.save(admin);
 
+    System.err.println("[DB FILLER] Users added");
+
     modelRepo.save(m1);
+    System.err.println("[DB FILLER] Model added");
   }
 
-  Set<Tag> tagLoader(String filePath) {
+  Set<Tag> tagLoader() {
     Set<Tag> tags = new HashSet<Tag>();
 
-    File file = new File(filePath);
-    FileReader fr;
+    Resource resource = new ClassPathResource("tags.txt");
+
     try {
-      fr = new FileReader(file);
-      BufferedReader br = new BufferedReader(fr);
+      BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
       String line;
       while ((line = br.readLine()) != null) {
         System.out.println("[DB FILLER] adding category "+line);
@@ -114,9 +117,9 @@ public class DatabaseFiller {
           line = br.readLine();
         }
       }
-      fr.close();
+      System.err.println("[DB FILLER] Tags added");
     } catch (IOException e) {
-      e.printStackTrace();
+      System.err.println("[DB FILLER] Tags failed");
     }   
 
     return tags;
diff --git a/mozen/src/main/java/mozen/web/ModelController.java b/mozen/src/main/java/mozen/web/ModelController.java
index 61a8bea273df4f1ecf61b3cc9375725bb6dba731..a3817d1b9e2c24f9b1a3767328d8eb297cf24eec 100644
--- a/mozen/src/main/java/mozen/web/ModelController.java
+++ b/mozen/src/main/java/mozen/web/ModelController.java
@@ -25,6 +25,7 @@ import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.messages.ModelMessage;
 import mozen.messages.ResponseMessage;
+import mozen.messages.TagCategoryMessage;
 import mozen.messages.TagMessage;
 import mozen.model.TagCategory;
 import mozen.model.User;
@@ -132,6 +133,24 @@ public class ModelController {
     return ResponseEntity.ok().build();
   }
 
+  @DeleteMapping("/tags")
+  public ResponseEntity<ResponseMessage> deleteTag(@RequestParam(value = "id", required = true) Long id) {
+    modelManager.removeTag(id);
+    return ResponseEntity.ok().build();
+  }
+
+  @PostMapping("/category")
+  public ResponseEntity<ResponseMessage> addCategory(@RequestBody @Valid TagCategoryMessage message) {
+    modelManager.addCategory(message);
+    return ResponseEntity.ok().build();
+  }
+
+  @DeleteMapping("/category")
+  public ResponseEntity<ResponseMessage> deleteCategory(@RequestParam(value = "id", required = true) Long id) {
+    modelManager.removeCategory(id);
+    return ResponseEntity.ok().build();
+  }
+
   @PostMapping("/upload")
   public ResponseEntity<ResponseMessage> uploadModelFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "id", required = true) Long id) {
     ResponseMessage response = new ResponseMessage(false, "");
diff --git a/tags.txt b/mozen/src/main/resources/tags.txt
similarity index 100%
rename from tags.txt
rename to mozen/src/main/resources/tags.txt
diff --git a/quickBuildToJar.sh b/quickBuildToJar.sh
new file mode 100755
index 0000000000000000000000000000000000000000..749df9d098309a16067a1556ac015d321710cb57
--- /dev/null
+++ b/quickBuildToJar.sh
@@ -0,0 +1,7 @@
+git clone https://gitlab.lis-lab.fr/thomas.blanc/ter-modelzoo-frontend.git
+cd ter-modelzoo-frontend
+npm install
+npm run build
+mv dist/* ../mozen/src/main/resources/public/
+cd ../mozen
+mvn package
\ No newline at end of file