Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/AdminController.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/AdminController.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/AdminController.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -0,0 +1,40 @@
+package finki.it.phoneluxbackend.controllers;
+
+import finki.it.phoneluxbackend.entities.PhoneOffer;
+import finki.it.phoneluxbackend.services.PhoneOfferService;
+import lombok.AllArgsConstructor;
+import org.apache.coyote.Response;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(path = "/admin")
+@AllArgsConstructor
+public class AdminController {
+    private PhoneOfferService phoneOfferService;
+
+
+    @PutMapping(path = "/editoffer/{offerId}", consumes = {
+            MediaType.APPLICATION_JSON_VALUE,
+            MediaType.APPLICATION_XML_VALUE
+    }, produces = {
+            MediaType.APPLICATION_JSON_VALUE,
+            MediaType.APPLICATION_XML_VALUE
+    })
+    public ResponseEntity<Object> editOffer(@PathVariable("offerId") Long offerId, @RequestBody PhoneOffer editedOffer){
+
+        return phoneOfferService.editOffer(offerId,editedOffer);
+    }
+
+    @PutMapping(path = "/validateoffer/{offerId}")
+    public ResponseEntity<Object> validateOffer(@PathVariable("offerId") Long offerId){
+        return phoneOfferService.validateOffer(offerId);
+    }
+
+
+    @GetMapping(path = "/editoffer/{offerId}")
+    public ResponseEntity<Object> getOffer(@PathVariable("offerId") Long offerId){
+        return ResponseEntity.ok().body(phoneOfferService.getPhoneOffer(offerId));
+    }
+}
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/PhoneOfferController.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/PhoneOfferController.java	(revision 7e88e4629bb341cb3730a26b5197ab06068ce0db)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/PhoneOfferController.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -7,8 +7,5 @@
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -22,4 +19,14 @@
     public List<PhoneOffer> getOffersForPhone(@PathVariable("phoneId") Long phoneId){
         return phoneOfferService.getPhoneOffersForPhone(phoneId);
+    }
+
+    @GetMapping(path = "/multipleoffers")
+    public List<PhoneOffer> getPhoneOffer(@RequestParam("offerIds") String offerIds){
+        return phoneOfferService.getMultiplePhoneOffers(offerIds);
+    }
+
+    @GetMapping(path = "/phoneoffer/shop/{shop}")
+    public List<PhoneOffer> getOffersFromShop(@PathVariable("shop") String shop){
+        return phoneOfferService.getOffersFromShop(shop);
     }
 
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/SpecificationsController.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/SpecificationsController.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/controllers/SpecificationsController.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -0,0 +1,72 @@
+package finki.it.phoneluxbackend.controllers;
+
+import finki.it.phoneluxbackend.services.PhoneOfferService;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping(path = "/specifications")
+public class SpecificationsController {
+    private final PhoneOfferService phoneOfferService;
+
+    // specifications endpoints
+    @GetMapping(path = "/ram")
+    public List<String> getRamMemories()
+    {
+        return phoneOfferService.getRamMemories();
+    }
+
+    @GetMapping(path = "/rom")
+    public List<String> getRomMemories()
+    {
+        return phoneOfferService.getRomMemories();
+    }
+
+    @GetMapping(path = "/color")
+    public List<String> getColors()
+    {
+        return phoneOfferService.getColors();
+    }
+
+    @GetMapping(path = "/chipset")
+    public List<String> getChipsets()
+    {
+        return phoneOfferService.getChipsets();
+    }
+
+    @GetMapping(path = "/cpu")
+    public List<String> getCPUs()
+    {
+        return phoneOfferService.getCPUs();
+    }
+
+    @GetMapping(path = "/frontcamera")
+    public List<String> getFrontCameras()
+    {
+        return phoneOfferService.getFrontCameras();
+    }
+
+    @GetMapping(path = "/backcamera")
+    public List<String> getBackCameras()
+    {
+        return phoneOfferService.getBackCameras();
+    }
+
+    @GetMapping(path = "/battery")
+    public List<String> getBatteries()
+    {
+        return phoneOfferService.getBatteries();
+    }
+
+    @GetMapping(path = "/operatingsystem")
+    public List<String> getOperatingSystems()
+    {
+        return phoneOfferService.getOperatingSystems();
+    }
+
+}
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/PhoneOffer.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/PhoneOffer.java	(revision 7e88e4629bb341cb3730a26b5197ab06068ce0db)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/PhoneOffer.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -14,4 +14,5 @@
 @Setter
 @ToString
+@EqualsAndHashCode
 @Entity(name = "PhoneOffer")
 @Table(name = "phone_offers")
@@ -76,4 +77,5 @@
 
     @ManyToMany(mappedBy = "favouriteOffers")
+    @JsonIgnore
     private List<User> users = new ArrayList<User>();
 
@@ -112,3 +114,43 @@
         this.phone = phone;
     }
+
+    public PhoneOffer(Long id,
+                      String offer_shop,
+                      String offer_name,
+                      Integer price,
+                      String ram_memory,
+                      String rom_memory,
+                      String color,
+                      String front_camera,
+                      String back_camera,
+                      String chipset,
+                      String battery,
+                      String operating_system,
+                      String cpu,
+                      String image_url,
+                      String offer_url,
+                      Date last_updated,
+                      Boolean is_validated,
+                      String offer_description,
+                      String offer_shop_code) {
+        this.id = id;
+        this.offer_shop = offer_shop;
+        this.offer_name = offer_name;
+        this.price = price;
+        this.ram_memory = ram_memory;
+        this.rom_memory = rom_memory;
+        this.color = color;
+        this.front_camera = front_camera;
+        this.back_camera = back_camera;
+        this.chipset = chipset;
+        this.battery = battery;
+        this.operating_system = operating_system;
+        this.cpu = cpu;
+        this.image_url = image_url;
+        this.offer_url = offer_url;
+        this.last_updated = last_updated;
+        this.is_validated = is_validated;
+        this.offer_description = offer_description;
+        this.offer_shop_code = offer_shop_code;
+    }
 }
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/User.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/User.java	(revision 7e88e4629bb341cb3730a26b5197ab06068ce0db)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/entities/User.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -52,4 +52,6 @@
     @JsonIgnore
     private List<PhoneOffer> favouriteOffers = new ArrayList<PhoneOffer>();
+
+    private String specifications;
 
     public User(String firstName, String lastName, String email, String password, UserRole userRole) {
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/security/configs/WebSecurityConfig.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/security/configs/WebSecurityConfig.java	(revision 7e88e4629bb341cb3730a26b5197ab06068ce0db)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/security/configs/WebSecurityConfig.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -43,4 +43,8 @@
                 .antMatchers("/management/**")
                 .hasAnyAuthority("SUPERADMIN")
+                .and()
+                .authorizeRequests()
+                .antMatchers("/admin/**")
+                .hasAnyAuthority("ADMIN","SUPERADMIN")
                 .anyRequest().permitAll();
 
Index: phonelux-backend/src/main/java/finki/it/phoneluxbackend/services/PhoneOfferService.java
===================================================================
--- phonelux-backend/src/main/java/finki/it/phoneluxbackend/services/PhoneOfferService.java	(revision 7e88e4629bb341cb3730a26b5197ab06068ce0db)
+++ phonelux-backend/src/main/java/finki/it/phoneluxbackend/services/PhoneOfferService.java	(revision 520169098d7257d32291e4ee85b94e1e499ede09)
@@ -1,13 +1,12 @@
 package finki.it.phoneluxbackend.services;
 
+import finki.it.phoneluxbackend.entities.Phone;
 import finki.it.phoneluxbackend.entities.PhoneOffer;
 import finki.it.phoneluxbackend.repositories.PhoneOfferRepository;
 import finki.it.phoneluxbackend.repositories.PhoneRepository;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
@@ -76,3 +75,212 @@
                 .collect(Collectors.toList());
     }
+
+    public ResponseEntity<Object> editOffer(Long offerId, PhoneOffer editedOffer) {
+        boolean exists = phoneOfferRepository.existsById(offerId);
+
+        if(!exists)
+            throw new IllegalStateException("Phone offer with id "+offerId+" does not exist");
+
+        PhoneOffer oldOffer = phoneOfferRepository.findById(offerId).get();
+
+        editedOffer.setPhone(oldOffer.getPhone());
+        editedOffer.setUsers(oldOffer.getUsers());
+        editedOffer.setIs_validated(false);
+        editedOffer.setLast_updated(new Date());
+
+        phoneOfferRepository.save(editedOffer);
+
+        return ResponseEntity.ok().build();
+    }
+
+    public ResponseEntity<Object> validateOffer(Long offerId) {
+        boolean exists = phoneOfferRepository.existsById(offerId);
+
+        if(!exists)
+            throw new IllegalStateException("Phone offer with id "+offerId+" does not exist");
+
+        PhoneOffer offer = phoneOfferRepository.findById(offerId).get();
+
+        offer.setIs_validated(true);
+        offer.setLast_updated(new Date());
+        phoneOfferRepository.save(offer);
+
+        return ResponseEntity.ok().build();
+    }
+
+    public List<PhoneOffer> getMultiplePhoneOffers(String offerIds) {
+        List<Long> idList = Arrays.stream(offerIds.split(","))
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+
+        List<PhoneOffer> phoneOffers = new ArrayList<>();
+
+        idList.stream().forEach(id -> {
+            phoneOffers.add(phoneOfferRepository.findById(id).get());
+        });
+
+        return phoneOffers;
+    }
+
+    public List<PhoneOffer> getOffersFromShop(String shop) {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .filter(offer -> offer.getOffer_shop().equalsIgnoreCase(shop))
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getRamMemories() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        List<String> temp = new ArrayList<>();
+
+        offers.stream()
+                .map(PhoneOffer::getRam_memory)
+                .filter(ram -> ram != null && (ram.toLowerCase().contains("gb") || ram.toLowerCase().contains("mb")))
+                .forEach(ram -> {
+                    temp.addAll(Arrays.asList(ram.replaceAll("\\s+", "")
+                                    .replaceAll("Ram", "")
+                            .split("[,/]")));
+                });
+
+        return getMemories(temp);
+    }
+
+    public List<String> getRomMemories() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        List<String> temp = new ArrayList<>();
+
+        offers.stream()
+                .map(PhoneOffer::getRom_memory)
+                .filter(rom -> rom != null && (rom.toLowerCase().contains("gb") || rom.toLowerCase().contains("mb")))
+                .forEach(ram -> {
+                    temp.addAll(Arrays.asList(ram.replaceAll("\\s+", "")
+                            .replaceAll("Rom", "")
+                            .replaceAll("storage", "")
+                            .split("[,/]")));
+                });
+
+        return getMemories(temp);
+    }
+
+    private List<String> getMemories(List<String> temp) {
+        List<String> memories = new ArrayList<>();
+
+        temp.stream()
+                .filter(memory -> memory.toLowerCase().contains("mb"))
+                .sorted()
+                .forEach(memories::add);
+
+        temp.stream()
+                .filter(memory -> memory.toLowerCase().contains("gb"))
+                .sorted()
+                .forEach(memories::add);
+
+
+        return memories.stream()
+                .filter(memory -> memory.matches("\\S*\\d+\\S*"))
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getColors() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+        List<String> colors = new ArrayList<>();
+
+        return offers.stream()
+                .map(PhoneOffer::getColor)
+                .filter(colorRow -> colorRow != null && !colorRow.equals("") && !colorRow.equals("/"))
+                .flatMap(color -> Arrays.stream(color.split(",")))
+                .map(String::stripIndent)
+                .filter(color -> !color.matches("\\S+\\d+\\S+") && !color.equals(""))
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getChipsets() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+        List<String> temp = new ArrayList<>();
+        List<String> chipsets = new ArrayList<>();
+
+        temp = offers.stream()
+                .map(PhoneOffer::getChipset)
+                .filter(chipset -> chipset != null && !chipset.equals("") && !chipset.equals("/"))
+                .distinct()
+                .collect(Collectors.toList());
+
+        temp.stream()
+                .forEach(chipset -> chipsets.add(chipset.replaceAll("5G ", "")));
+
+        return chipsets.stream()
+                .filter(chipset -> !chipset.contains("\r"))
+                .map(offer -> offer.split("\\(")[0].stripIndent())
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getCPUs() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .map(PhoneOffer::getCpu)
+                .filter(cpu -> cpu!=null && !cpu.equals("") && !cpu.equals("/"))
+                .map(cpu -> cpu.split("\n")[0].stripIndent().replaceAll("\n",""))
+                .filter(cpu -> !cpu.contains("Snapdragon") && !cpu.contains("Exynos"))
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getFrontCameras() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .map(PhoneOffer::getFront_camera)
+                .filter(camera -> camera != null && !camera.equals("") && !camera.equals("/"))
+                .map(camera -> camera.split("MP")[0].stripIndent()+"MP")
+                .filter(camera -> !camera.contains("\n"))
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getBackCameras() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .map(PhoneOffer::getBack_camera)
+                .filter(camera -> camera != null && !camera.equals("") && !camera.equals("/"))
+                .map(camera -> camera.split("[\n,]")[0].replaceAll("\t",""))
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getBatteries() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .map(PhoneOffer::getBattery)
+                .filter(battery -> battery != null && !battery.equals("") && !battery.equals("/"))
+                .map(battery -> battery.split(",")[0].stripIndent())
+                .distinct()
+                .sorted(Comparator.reverseOrder())
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getOperatingSystems() {
+        List<PhoneOffer> offers = phoneOfferRepository.findAll();
+
+        return offers.stream()
+                .map(PhoneOffer::getOperating_system)
+                .filter(os -> os != null && !os.equals("") && !os.equals("/"))
+                .map(os -> os.split("[,(-]")[0].stripIndent())
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+    }
 }
