From 06adeea855240b924e58a4fd69ed88643c6149e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Fri, 11 Aug 2023 22:19:57 -0300 Subject: [PATCH 01/17] added spring-data-rest to POM file, delted unused folders --- pom.xml | 5 ++ .../rest/EmployeeRestController.java | 68 ------------------ .../service/EmployeeService.java | 16 ----- .../service/EmployeeServiceImpl.java | 53 -------------- .../dao/EmployeeRepository.class | Bin 0 -> 380 bytes .../rest/EmployeeRestController.class | Bin 0 -> 3254 bytes .../service/EmployeeServiceImpl.class | Bin 0 -> 2776 bytes 7 files changed, 5 insertions(+), 137 deletions(-) delete mode 100644 src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java delete mode 100644 src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java delete mode 100644 src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java create mode 100644 target/classes/com/manumiguezz/crudapplication/dao/EmployeeRepository.class create mode 100644 target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class create mode 100644 target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class diff --git a/pom.xml b/pom.xml index a4e1e3d..976738c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,10 +17,15 @@ 17 + + org.springframework.boot + spring-boot-starter-data-rest + org.springframework.boot spring-boot-starter-data-jpa + org.springframework.boot spring-boot-starter-web diff --git a/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java b/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java deleted file mode 100644 index 13a5acd..0000000 --- a/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.manumiguezz.crudapplication.rest; - -import com.manumiguezz.crudapplication.dao.EmployeeDAO; -import com.manumiguezz.crudapplication.entity.Employee; -import com.manumiguezz.crudapplication.service.EmployeeService; -import com.manumiguezz.crudapplication.service.EmployeeServiceImpl; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/api") -public class EmployeeRestController { - - private EmployeeService employeeService; - - public EmployeeRestController (EmployeeService theEmployeeService) { - employeeService = theEmployeeService; - } - - @GetMapping("/employees") - public List findAll(){ - return employeeService.findAll(); - } - - @GetMapping("/employees/{employeeId}") - public Employee getEmployee(@PathVariable int employeeId) { - Employee theEmployee = employeeService.findById(employeeId); - - if (theEmployee == null) { - throw new RuntimeException("Employee id not found - " + employeeId); - } - - return theEmployee; - } - - @PostMapping ("/employees") - public Employee addEmployee(@RequestBody Employee theEmployee) { - - theEmployee.setId(0); - - Employee dbEmployee = employeeService.save(theEmployee); - return dbEmployee; - } - - @PutMapping("/employees") - public Employee updateEmployee(@RequestBody Employee theEmployee) { - Employee dbEmployee = employeeService.save(theEmployee); - return dbEmployee; - } - - @DeleteMapping("/employees/{employeeId} ") - public String deleteEmployee(@PathVariable int employeeId) { - Employee tempEmployee = employeeService.findById(employeeId); - - if (tempEmployee == null) { - throw new RuntimeException("Employee id: " + employeeId + " not found"); - } - - employeeService.deleteByID(employeeId); - - return "Employee with id: " + employeeId + " was deleted"; - } - - - - -} diff --git a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java deleted file mode 100644 index ff56fdb..0000000 --- a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.manumiguezz.crudapplication.service; - -import com.manumiguezz.crudapplication.entity.Employee; - -import java.util.List; - -public interface EmployeeService { - List findAll(); - - Employee findById(int theId); - - Employee save(Employee theEmployee); - - void deleteByID(int theId); - -} diff --git a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java deleted file mode 100644 index 6acf772..0000000 --- a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.manumiguezz.crudapplication.service; - -import com.manumiguezz.crudapplication.dao.EmployeeDAO; -import com.manumiguezz.crudapplication.dao.EmployeeRepository; -import com.manumiguezz.crudapplication.entity.Employee; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - -@Service -public class EmployeeServiceImpl implements EmployeeService{ - - private EmployeeRepository employeeRepository; - - @Autowired - public EmployeeServiceImpl (EmployeeRepository theEmployeeRepository) { - employeeRepository = theEmployeeRepository; - } - - @Override - public List findAll() { - return employeeRepository.findAll(); - } - - @Override - public Employee findById(int theId) { - Optional result = employeeRepository.findById(theId); - - Employee theEmployee; - - if (result.isPresent()) { - theEmployee = result.get(); - } - else { - throw new RuntimeException("Did not find employee id: " + theId); - } - - return theEmployee; - } - - @Override - public Employee save(Employee theEmployee) { - return employeeRepository.save(theEmployee); - } - - @Override - public void deleteByID(int theId) { - employeeRepository.deleteById(theId); - } -} diff --git a/target/classes/com/manumiguezz/crudapplication/dao/EmployeeRepository.class b/target/classes/com/manumiguezz/crudapplication/dao/EmployeeRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..1d2b90478bf1214db37e7022f569317004d1fae9 GIT binary patch literal 380 zcmbV|Jx&BM3`U*hXV|5o;}*DrW`GVP&`3z^2~5^R876V$O+d4k;64-_fI}g|77Ky` ziNbdG{Jrn({pA$^&S1ZRiGdR<0RzPnyeqs~q1CdWlm>4pdx^Lp!HbXv8JTZ6$bSa z2A;d0=(hV8_O$!Uk7M?E+$gr+K3~Pmjg?2p O0VdF__a02wclH6d!F|*K literal 0 HcmV?d00001 diff --git a/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class b/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class new file mode 100644 index 0000000000000000000000000000000000000000..9e92e8b5da7677c629518dc4173952f4be2d9201 GIT binary patch literal 3254 zcmbVOZC4XV6n+K*2}yV{RZ&riij{z}wM9{bR6$hQpp@9CwQrN`5LPz3>Fz8Pd-@0Z z3;HwKbJ}{e=d>StPJdHRPw(t*c7uRGKV&m^=FYv(eeRt*^Y_26{{V0kt7&wgGl@hN zUFc>Qc+S_kW^${pJ*++#HObIDZCHk!Vdxw!RCR)VMTkOLK%PwfRQVv^RxVCSlIDq+^?=a2WbUxKI|(x=|Ah*GqdDbOY7M zX1KMOK_B{)7|7xfatu@d(+)#&#jy0-rpb^SEtGsZJZYF($#A9bWbd@dQtk_)PWlXAC28$2P2WdrfFT;|^NBR5rMq4@!%=Kz6~h zgfnMy*A;FOG;@9%YdevV#0tadx2w{tCSZ<}UHVt+ z>9Ln!W8=Rf`7=o!xJ=(ZbkcVK33_w%Acyx!IvQx>15A=c`*4MEd%|dEXmUHoIozT7qzZhV28=i^gn*xrB?UM) z-uWBy3ibFaysJ>hv;?eQpd1y5`>{5Bxd>m*M@46m?A`P6g@|sE@fM={ z^ihQ9VTh=AXE5sd3@Vlk@vZU{5Y-z2=?#Ho-Uj63-GP*FGNk4QB1Ta&v2!lRf?S4+ z;~k*H=l=Ig|NAwnw34RT8U*S%{vQFiQ!fAj literal 0 HcmV?d00001 diff --git a/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class b/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3008d1ddbb0f85385bcff9a3b9fcebbfec6c52ea GIT binary patch literal 2776 zcmbVOYf}?f7=BI&EQAmh1x1RD7Bzsds8p#zTR_m%0M^i0Yj20_AspH4W_CAN{3Y!# z=+}0pt(VTU{oLQ=bo!pXBnv__!-u`R@4naPy`25$-#32(xQ%KG33O;krqPKmhU3rp z4%ba?RrR%vXQJXUbj?XidUqH)a%1HlbfZT@Dve&G8S)jorq{UDsL5(Wym+BkoQA>c zbyHTjCv8i2g|j0oLSL%YO?y{}Qa~4oWat+m_mQaEuJmkYmtnTp&ZfcbroEPCz84uB z({MbE6X<8SaWpdw+NQLOc~ixg8!P&FG(2hQMd^C^6i#74!(bYxafabU3$B9YiK=i& ze}|h5v9`%Dm@9+^d_Y49KhU#j4C6h9ZslxYw_q^ja)GlL`1!d1wYox-n-s%2yssgf z#(7+zC|e;$A`Cs!edq{RSX4l&+m}jbG>wb6M08aU_f(Wz+@FRVgWe7~vMRmZW(_oq zGn{Q9@u)%HYhvm9itt13r%t<)#w4Z~PS^OhShOu_kH^y6qBqy$mgh1I>;wLo`PJhv^aI?%EspycI z^tL2Hdb_R1L!wpVNy!d)TOu0V)}YanSP|ZqZ9L=-uMubtxf%+KUY4$;IOZ+O_WTV% z-)4)pQ`OzND(I$Cd2Tz~`i9_^t8em(8hf2L74-RrXFr#YFerkalB`Nd6sXF>h)N--2 zVoGfnT9F5Kl1nWpY>zO~Llpw>_=0VFuIKQ2(5&vUF3=Wyimx<$t(MU@45O``C9NHM zoAmvy6YQtupfwqOh_91SFfe+bTZSpz(V}f{H|qI!*HetMM{%8kJwW_vOg`E>F;-|| zk(*{odLrMA?-+*fN+V0tmQ^Q7HabzW(zumn4C#Vp31`vdt}9#(6^4uNBz;gW8mJQI z{$G^3I7pn%p>Fz(V7NtBLj4)g#_y!}PRyZ${xX1N;wR{t8h;5kKJgp0Ux-TJ4&5^( z1N0+_ljx!I^<$z218IDMd7?-U3uKjHk={EQ5x`x#x`?$zPdbUoK*D!5Llh%kYW!Dd zuhGZwGf{ynB@dkOT_|(PaNuIum$^s0VcZWby`sR9#Gh7{hF{_2YYZi@a^-i7{D=%a zKKL7#SAW8ZKQQ)W_zfn2m(c&3RQ{5FYJ&s;FhVJw#{e!MODFIYa=!l=`Zhuy3i#9q zV7i&?G#;Qxkz`0?1*;Uz6kUPb8rf5k2j3nN|1;ubka&x%hI4Pxr{Qu0(*ycM3lERN zgcj(TP~s|~iPyN60A;Wrp2=7RGR>eeegMr16nxVqtcRwf0{f-|tZpRGDzf^|1g@bE r*AFot Date: Sun, 13 Aug 2023 21:46:31 -0300 Subject: [PATCH 02/17] page size adjusted, base path changed --- src/main/resources/application.properties | 5 ++++- target/classes/application.properties | 5 ++++- .../rest/EmployeeRestController.class | Bin 3254 -> 0 bytes .../service/EmployeeService.class | Bin 576 -> 0 bytes .../service/EmployeeServiceImpl.class | Bin 2776 -> 0 bytes 5 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class delete mode 100644 target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class delete mode 100644 target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4a4b39a..f95f4bc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,7 @@ spring.datasource.url=jdbc:mysql://localhost:3306/employee_directory spring.datasource.username=springstudent -spring.datasource.password=springstudent \ No newline at end of file +spring.datasource.password=springstudent + +spring.data.rest.base-path=/company-api +spring.data.rest.default-page-size=40 \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties index 4a4b39a..f95f4bc 100644 --- a/target/classes/application.properties +++ b/target/classes/application.properties @@ -1,4 +1,7 @@ spring.datasource.url=jdbc:mysql://localhost:3306/employee_directory spring.datasource.username=springstudent -spring.datasource.password=springstudent \ No newline at end of file +spring.datasource.password=springstudent + +spring.data.rest.base-path=/company-api +spring.data.rest.default-page-size=40 \ No newline at end of file diff --git a/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class b/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class deleted file mode 100644 index 9e92e8b5da7677c629518dc4173952f4be2d9201..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3254 zcmbVOZC4XV6n+K*2}yV{RZ&riij{z}wM9{bR6$hQpp@9CwQrN`5LPz3>Fz8Pd-@0Z z3;HwKbJ}{e=d>StPJdHRPw(t*c7uRGKV&m^=FYv(eeRt*^Y_26{{V0kt7&wgGl@hN zUFc>Qc+S_kW^${pJ*++#HObIDZCHk!Vdxw!RCR)VMTkOLK%PwfRQVv^RxVCSlIDq+^?=a2WbUxKI|(x=|Ah*GqdDbOY7M zX1KMOK_B{)7|7xfatu@d(+)#&#jy0-rpb^SEtGsZJZYF($#A9bWbd@dQtk_)PWlXAC28$2P2WdrfFT;|^NBR5rMq4@!%=Kz6~h zgfnMy*A;FOG;@9%YdevV#0tadx2w{tCSZ<}UHVt+ z>9Ln!W8=Rf`7=o!xJ=(ZbkcVK33_w%Acyx!IvQx>15A=c`*4MEd%|dEXmUHoIozT7qzZhV28=i^gn*xrB?UM) z-uWBy3ibFaysJ>hv;?eQpd1y5`>{5Bxd>m*M@46m?A`P6g@|sE@fM={ z^ihQ9VTh=AXE5sd3@Vlk@vZU{5Y-z2=?#Ho-Uj63-GP*FGNk4QB1Ta&v2!lRf?S4+ z;~k*H=l=Ig|NAwnw34RT8U*S%{vQFiQ!fAj diff --git a/target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class b/target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class deleted file mode 100644 index fb6d74a8ea19e09050637f0d827a1a3b6ccf60dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 576 zcmbV}%}&BV6ot>lLizCrk%xedvoUdjnrOs?1fvOw`?0;2A=8$$QxbSI7e0UwWxPd^ zg$skrbLQmCckg}wczpwKiLQ?d;XFuV73-vkO;qq|rGl&o^?Ytkpq)t*m2TWR81w(=>e4nU2|UmJ_OO%4MUM>xHm} zy`5|S1JaUTH;X1TL$-n=qumOKjP@knBrURl?~E0y?k4+vl+$wGH3DHzP7HW*qbh2m leNh$EMK{nC-4b0T>`R7lfWxhIw6@wf-dd6p(OFlVd;;`jrXK(R diff --git a/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class b/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class deleted file mode 100644 index 3008d1ddbb0f85385bcff9a3b9fcebbfec6c52ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2776 zcmbVOYf}?f7=BI&EQAmh1x1RD7Bzsds8p#zTR_m%0M^i0Yj20_AspH4W_CAN{3Y!# z=+}0pt(VTU{oLQ=bo!pXBnv__!-u`R@4naPy`25$-#32(xQ%KG33O;krqPKmhU3rp z4%ba?RrR%vXQJXUbj?XidUqH)a%1HlbfZT@Dve&G8S)jorq{UDsL5(Wym+BkoQA>c zbyHTjCv8i2g|j0oLSL%YO?y{}Qa~4oWat+m_mQaEuJmkYmtnTp&ZfcbroEPCz84uB z({MbE6X<8SaWpdw+NQLOc~ixg8!P&FG(2hQMd^C^6i#74!(bYxafabU3$B9YiK=i& ze}|h5v9`%Dm@9+^d_Y49KhU#j4C6h9ZslxYw_q^ja)GlL`1!d1wYox-n-s%2yssgf z#(7+zC|e;$A`Cs!edq{RSX4l&+m}jbG>wb6M08aU_f(Wz+@FRVgWe7~vMRmZW(_oq zGn{Q9@u)%HYhvm9itt13r%t<)#w4Z~PS^OhShOu_kH^y6qBqy$mgh1I>;wLo`PJhv^aI?%EspycI z^tL2Hdb_R1L!wpVNy!d)TOu0V)}YanSP|ZqZ9L=-uMubtxf%+KUY4$;IOZ+O_WTV% z-)4)pQ`OzND(I$Cd2Tz~`i9_^t8em(8hf2L74-RrXFr#YFerkalB`Nd6sXF>h)N--2 zVoGfnT9F5Kl1nWpY>zO~Llpw>_=0VFuIKQ2(5&vUF3=Wyimx<$t(MU@45O``C9NHM zoAmvy6YQtupfwqOh_91SFfe+bTZSpz(V}f{H|qI!*HetMM{%8kJwW_vOg`E>F;-|| zk(*{odLrMA?-+*fN+V0tmQ^Q7HabzW(zumn4C#Vp31`vdt}9#(6^4uNBz;gW8mJQI z{$G^3I7pn%p>Fz(V7NtBLj4)g#_y!}PRyZ${xX1N;wR{t8h;5kKJgp0Ux-TJ4&5^( z1N0+_ljx!I^<$z218IDMd7?-U3uKjHk={EQ5x`x#x`?$zPdbUoK*D!5Llh%kYW!Dd zuhGZwGf{ynB@dkOT_|(PaNuIum$^s0VcZWby`sR9#Gh7{hF{_2YYZi@a^-i7{D=%a zKKL7#SAW8ZKQQ)W_zfn2m(c&3RQ{5FYJ&s;FhVJw#{e!MODFIYa=!l=`Zhuy3i#9q zV7i&?G#;Qxkz`0?1*;Uz6kUPb8rf5k2j3nN|1;ubka&x%hI4Pxr{Qu0(*ycM3lERN zgcj(TP~s|~iPyN60A;Wrp2=7RGR>eeegMr16nxVqtcRwf0{f-|tZpRGDzf^|1g@bE r*AFot Date: Mon, 14 Aug 2023 17:56:43 -0300 Subject: [PATCH 03/17] DAO classes deleted, rest controller added again, errors to be fixed --- .../crudapplication/dao/EmployeeDAO.java | 15 --- .../dao/EmployeeDAOJpaImpl.java | 50 ---------- .../rest/EmployeeRestController.java | 97 +++++++++++++++++++ 3 files changed, 97 insertions(+), 65 deletions(-) delete mode 100644 src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAO.java delete mode 100644 src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAOJpaImpl.java create mode 100644 src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java diff --git a/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAO.java b/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAO.java deleted file mode 100644 index e6f13fe..0000000 --- a/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAO.java +++ /dev/null @@ -1,15 +0,0 @@ -//package com.manumiguezz.crudapplication.dao; -// -//import com.manumiguezz.crudapplication.entity.Employee; -// -//import java.util.List; -// -//public interface EmployeeDAO { -// List findAll(); -// -// Employee findById(int theId); -// -// Employee save(Employee theEmployee); -// -// void deleteByID(int theId); -//} diff --git a/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAOJpaImpl.java b/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAOJpaImpl.java deleted file mode 100644 index 6008827..0000000 --- a/src/main/java/com/manumiguezz/crudapplication/dao/EmployeeDAOJpaImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -//package com.manumiguezz.crudapplication.dao; -// -//import com.manumiguezz.crudapplication.entity.Employee; -//import jakarta.persistence.EntityManager; -//import jakarta.persistence.TypedQuery; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.stereotype.Repository; -// -//import java.util.List; -// -//@Repository -//public class EmployeeDAOJpaImpl implements EmployeeDAO { -// -// private EntityManager entityManager; -// -// @Autowired -// public EmployeeDAOJpaImpl(EntityManager theEntityManager) { -// entityManager = theEntityManager; -// } -// -// @Override -// public List findAll() { -// -// TypedQuery theQuery = entityManager.createQuery("from Employee", Employee.class); -// -// List employees = theQuery.getResultList(); -// -// return employees; -// } -// -// @Override -// public Employee findById(int theId) { -// Employee theEmployee = entityManager.find(Employee.class, theId); -// return theEmployee; -// } -// -// @Override -// public Employee save(Employee theEmployee) { -// // if ID of passed employee is equal to 0, it will insert a new one, else it will just update -// Employee dbEmployee = entityManager.merge(theEmployee); -// return dbEmployee; -// } -// -// @Override -// public void deleteByID(int theId) { -// Employee theEmployee = entityManager.find(Employee.class, theId); -// entityManager.remove(theEmployee); -// } -// -//} diff --git a/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java b/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java new file mode 100644 index 0000000..1c7a781 --- /dev/null +++ b/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java @@ -0,0 +1,97 @@ +package com.manumiguezz.crudapplication.rest; + +import com.manumiguezz.crudapplication.entity.Employee; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api") +public class EmployeeRestController { + + private Employee employeeService; + + @Autowired + public EmployeeRestController(EmployeeService theEmployeeService) { + employeeService = theEmployeeService; + } + + // expose "/employees" and return a list of employees + @GetMapping("/employees") + public List findAll() { + return employeeService.findAll(); + } + + // add mapping for GET /employees/{employeeId} + + @GetMapping("/employees/{employeeId}") + public Employee getEmployee(@PathVariable int employeeId) { + + Employee theEmployee = employeeService.findById(employeeId); + + if (theEmployee == null) { + throw new RuntimeException("Employee id not found - " + employeeId); + } + + return theEmployee; + } + + // add mapping for POST /employees - add new employee + + @PostMapping("/employees") + public Employee addEmployee(@RequestBody Employee theEmployee) { + + // also just in case they pass an id in JSON ... set id to 0 + // this is to force a save of new item ... instead of update + + theEmployee.setId(0); + + Employee dbEmployee = employeeService.save(theEmployee); + + return dbEmployee; + } + + // add mapping for PUT /employees - update existing employee + + @PutMapping("/employees") + public Employee updateEmployee(@RequestBody Employee theEmployee) { + + Employee dbEmployee = employeeService.save(theEmployee); + + return dbEmployee; + } + + // add mapping for DELETE /employees/{employeeId} - delete employee + + @DeleteMapping("/employees/{employeeId}") + public String deleteEmployee(@PathVariable int employeeId) { + + Employee tempEmployee = employeeService.findById(employeeId); + + // throw exception if null + + if (tempEmployee == null) { + throw new RuntimeException("Employee id not found - " + employeeId); + } + + employeeService.deleteById(employeeId); + + return "Deleted employee id - " + employeeId; + } + +} + + + + + + + + + + + + + + From f80329a7ef1a7be1ef9a4b9814de01eea05c2c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Mon, 14 Aug 2023 18:03:43 -0300 Subject: [PATCH 04/17] service layer added again --- .../rest/EmployeeRestController.java | 14 +---- .../service/EmployeeService.java | 18 ++++++ .../service/EmployeeServiceImpl.java | 58 +++++++++++++++++++ 3 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java create mode 100644 src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java diff --git a/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java b/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java index 1c7a781..ad1fc54 100644 --- a/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java +++ b/src/main/java/com/manumiguezz/crudapplication/rest/EmployeeRestController.java @@ -1,6 +1,7 @@ package com.manumiguezz.crudapplication.rest; import com.manumiguezz.crudapplication.entity.Employee; +import com.manumiguezz.crudapplication.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -10,20 +11,18 @@ @RequestMapping("/api") public class EmployeeRestController { - private Employee employeeService; + private EmployeeService employeeService; @Autowired public EmployeeRestController(EmployeeService theEmployeeService) { employeeService = theEmployeeService; } - // expose "/employees" and return a list of employees @GetMapping("/employees") public List findAll() { return employeeService.findAll(); } - // add mapping for GET /employees/{employeeId} @GetMapping("/employees/{employeeId}") public Employee getEmployee(@PathVariable int employeeId) { @@ -37,13 +36,10 @@ public Employee getEmployee(@PathVariable int employeeId) { return theEmployee; } - // add mapping for POST /employees - add new employee @PostMapping("/employees") public Employee addEmployee(@RequestBody Employee theEmployee) { - // also just in case they pass an id in JSON ... set id to 0 - // this is to force a save of new item ... instead of update theEmployee.setId(0); @@ -52,8 +48,6 @@ public Employee addEmployee(@RequestBody Employee theEmployee) { return dbEmployee; } - // add mapping for PUT /employees - update existing employee - @PutMapping("/employees") public Employee updateEmployee(@RequestBody Employee theEmployee) { @@ -62,15 +56,11 @@ public Employee updateEmployee(@RequestBody Employee theEmployee) { return dbEmployee; } - // add mapping for DELETE /employees/{employeeId} - delete employee - @DeleteMapping("/employees/{employeeId}") public String deleteEmployee(@PathVariable int employeeId) { Employee tempEmployee = employeeService.findById(employeeId); - // throw exception if null - if (tempEmployee == null) { throw new RuntimeException("Employee id not found - " + employeeId); } diff --git a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java new file mode 100644 index 0000000..ea2f973 --- /dev/null +++ b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeService.java @@ -0,0 +1,18 @@ +package com.manumiguezz.crudapplication.service; + + +import com.manumiguezz.crudapplication.entity.Employee; + +import java.util.List; + +public interface EmployeeService { + + List findAll(); + + Employee findById(int theId); + + Employee save(Employee theEmployee); + + void deleteById(int theId); + +} diff --git a/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java new file mode 100644 index 0000000..8964a1c --- /dev/null +++ b/src/main/java/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.java @@ -0,0 +1,58 @@ +package com.manumiguezz.crudapplication.service; + + +import com.manumiguezz.crudapplication.dao.EmployeeRepository; +import com.manumiguezz.crudapplication.entity.Employee; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class EmployeeServiceImpl implements EmployeeService { + + private EmployeeRepository employeeRepository; + + @Autowired + public EmployeeServiceImpl(EmployeeRepository theEmployeeRepository) { + employeeRepository = theEmployeeRepository; + } + + @Override + public List findAll() { + return employeeRepository.findAll(); + } + + @Override + public Employee findById(int theId) { + Optional result = employeeRepository.findById(theId); + + Employee theEmployee = null; + + if (result.isPresent()) { + theEmployee = result.get(); + } + else { + throw new RuntimeException("Did not find employee id - " + theId); + } + + return theEmployee; + } + + @Override + public Employee save(Employee theEmployee) { + return employeeRepository.save(theEmployee); + } + + @Override + public void deleteById(int theId) { + employeeRepository.deleteById(theId); + } +} + + + + + + From 64ab52f2c118350bf522e4d7dba03c523ffa8576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Tue, 15 Aug 2023 19:17:46 -0300 Subject: [PATCH 05/17] application properties updated, password and username set, spring security dependency added, --- pom.xml | 10 ++++++++++ src/main/resources/application.properties | 5 ++++- target/classes/application.properties | 5 ++++- .../rest/EmployeeRestController.class | Bin 0 -> 3249 bytes .../service/EmployeeService.class | Bin 0 -> 576 bytes .../service/EmployeeServiceImpl.class | Bin 0 -> 2758 bytes 6 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class create mode 100644 target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class create mode 100644 target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class diff --git a/pom.xml b/pom.xml index 976738c..1baccf0 100644 --- a/pom.xml +++ b/pom.xml @@ -17,10 +17,17 @@ 17 + + + org.springframework.boot + spring-boot-starter-security + + org.springframework.boot spring-boot-starter-data-rest + org.springframework.boot spring-boot-starter-data-jpa @@ -37,16 +44,19 @@ runtime true + com.mysql mysql-connector-j runtime + org.springframework.boot spring-boot-starter-test test + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f95f4bc..8e8ddad 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,4 +4,7 @@ spring.datasource.username=springstudent spring.datasource.password=springstudent spring.data.rest.base-path=/company-api -spring.data.rest.default-page-size=40 \ No newline at end of file +spring.data.rest.default-page-size=40 + +spring.security.user.name=example +spring.security.user.password=example \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties index f95f4bc..8e8ddad 100644 --- a/target/classes/application.properties +++ b/target/classes/application.properties @@ -4,4 +4,7 @@ spring.datasource.username=springstudent spring.datasource.password=springstudent spring.data.rest.base-path=/company-api -spring.data.rest.default-page-size=40 \ No newline at end of file +spring.data.rest.default-page-size=40 + +spring.security.user.name=example +spring.security.user.password=example \ No newline at end of file diff --git a/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class b/target/classes/com/manumiguezz/crudapplication/rest/EmployeeRestController.class new file mode 100644 index 0000000000000000000000000000000000000000..a82df706842543cd62a07c98d113f2f237c91317 GIT binary patch literal 3249 zcmbVO>r&fB6#fI3-Eb+uB+{L6%%;1tp!n zK%bzG(ayBZB%Nu0cBaqN>GZ55OC~s6`or>G&Yts~?_75O{`b`%0B%C0(S~*nsVq9s z$^e$8C-#q;NS z)%6WtuUlr7OVhD+S9nsNuhlJQTZmraG zjutcMMW2TLERG<@aP5EUVbE4h+nBK|hTKS@6wu*I)6z?(Cj%?TvN(gLs?2BC3(v;gV@S=vd7)~X8FZ(1=6Z79zMO|^1qX3=CVi2bp25Njm5Ou`rBU7%^ z$dlZb9>Z~EI#E)Vu4%6o(-^=R71CiPv3tL;lE&LOtKnQ0=W&5S-;b}?&@*&+LMq== z1Ykw6e=&;@6llTYn-of8ev zJU*b$_|n-jU15;0r!0AOgHS|a9Z0O}-zDb0 zXE?hv0&#G5gyQOfeP7~oy^&JneTExGlcPo@nOr%zPRDB^^x)@~#Wz0n>RHFwCMdmr z-QY6L%EJV7$#1gX8y0BdNLCV|$@JQR{kk1gdXg&Xvg5l|amQ5EIoQy+^SYT(P4Z2( z(JC2t9w#1JmsRVd0e=a=l+NoW-LA8aBR%QzdRWk2Uni&&Kf+@TPgJY_jNyFJ%uRdK z*${fz)5Gq6CoErvADg>+Bp52a$8EzB-uaT_Z20x!?&jaLvg6>x?Yd|o{qucW7Ph zr$=9ajgI{a?Pr>`;a&Rnk__mPkwOmLIEu?OI}u9bJ-kmdI)_Qp%5a6o9aJy$ca?t1 z$Tj+B>Wvbanxq+{we;vO&|ad4;U}7frj$JBCRZkuI;A)?aXpZ^5oqnDoe$_&dxTP!%F+$OB`*(;`m=U@;e5e48Foi;01>M99JgW1MhNl5I94uwhSTaBT9xS3Kxm`guaOw^+X)rb67lBc<;wPycXUR9+2HO nECsyhX!Hrqmt*lV9@4y*)<31Sr@{9Nd_`+%ntzQ744nKA5l~Z^ literal 0 HcmV?d00001 diff --git a/target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class b/target/classes/com/manumiguezz/crudapplication/service/EmployeeService.class new file mode 100644 index 0000000000000000000000000000000000000000..32b1e2716dca5fd6590a52e33472ae91dcb2341e GIT binary patch literal 576 zcmbV}%}&BV6ot>lLizCrk%xedvoUdjnrMOv2}TnV_hWl4L#8chrzG%bE_?tV%6JPR z3l|2L-iOK7Ks%ErD(7rr0#?I# zZqp_6WWzo@LVKncT3MY$>hWd9fg|{@CJAq?C3JfI@%p`R#;UQ&-GI=Tm?+V%$e1wv zWw;vu)rJ#i-14W);6^g*<(GHMQAoJxjrx0M$Q%#srfK-3Gaa+zEGJaml*>df*9++y z_V$kbPmz}Vx?MD(8M2i+o6$TO?OC)*T4Vv=8!N54TkrQ#&dYt*2!sPUG2qFKs;CM3 jLKW178)yo*gsX%@@eq!1ypvAWQX8i`Nn8S*b;Q{h1=FTK literal 0 HcmV?d00001 diff --git a/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class b/target/classes/com/manumiguezz/crudapplication/service/EmployeeServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d74acc3f672ed939f844fd7264559a208b8609d7 GIT binary patch literal 2758 zcmbVOds7ov6#v~2ScpqNRD9qgwV(-#>#Ir|wFLxC8y+<_R_*JOT*8&jZe|}?{3Pus z=)bMg)@o*z%v!|*e{ z$qkcR4P$xrnW%XTeYd0~y*ms&`9gI7{TR@Y(QyDeL$PKzjV8DJrfm4)#S5e6_;ucD znX<+`X(6FYtpLEm@2+}p&a1hd(t$@()EfN9L5n1qdJb_7{kF1TqVmB4dIaf zCO3Vtyv8t^FGU6dKqHAD&=WewaFU^4Ih)-o)fw{n&{+cfV$%O|OCiclis3ZQXvpb! z2WKhDPKdDx!+>;G9N`L!3P^Q(qIAY}OyC^R4ME()adJt28uAQAH{{5w^tReH&@jnx zqJzW(pU#_N{@a=eLLQ+`yQpIdml%#V`G%OYEozTP(p#q|*W;GwG91|sR>gCq)u3Dp zxU72fijqhG6rC5Us_fTvT*rG1X_s#bhI2{5u#ICRlgTR0n>wcPK0~H1OyP;J65AZb z`c(}@hMV26*`wiURPy_6>_U|?o3rbb*-%+pV##l=3g;nTHHkA)wrkw1az`pUVy3-y zNs!*|>T!=~)p$~}N4#|r4{m4BXh|#zZ{4o1aECVuG>2RrkBVNEuB13-EX($S4M1np zW!q^OZc7z(O{qM$oeg7EaLYB;cukGH!P^SPjPKdcr6cMT!9YbeEbjRZWjY@>YxAtQEJmb4s1MKDw&!{dZ-xEo4)x)222b!*!xw7*e9180SyR&5v^PjUSTx~E zS_r$5;k)Dpi3CHV_qkO!g*#rh?G3+Ge0w7$INKB-Qn0&-KTXKTt0uvUOw4i9tVmB3 z`|&ly$-Ab21q`=a|zp5;a{f0xYaXf`Zwsi4VocbPFy1n}s z&M*CdgTJHjc0Iy*DIi)M@(hLvsG~SbzX@DMK8Rv6^w3W9DoXg6 zqR3(#pP)>U43qpKmME5GvZSI8&sON{(}0uu2WK^$)^L6>2B<^_wBGO_N@bSrDdJ^S zDi>bkY6=wjPGF`I*k{`zWdrwZ>=y&m)2KwIOKR kt0GV1A^oTDS-Z$pq94)KPg#9V*H`$4s0=-E)F5#DKWI Date: Tue, 15 Aug 2023 20:11:18 -0300 Subject: [PATCH 06/17] security config layer added, configuration class implemented, requestmatchers added --- .../security/SecurityConfig.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java diff --git a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java new file mode 100644 index 0000000..6814036 --- /dev/null +++ b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java @@ -0,0 +1,58 @@ +package com.manumiguezz.crudapplication.security; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class SecurityConfig { + + @Bean + public InMemoryUserDetailsManager UserDetailsManager() { + + UserDetails ramiro = User.builder() + .username("ramiro") + .password("{noop}examplepass") + .roles("EMPLOYEE") + .build(); + + UserDetails matias = User.builder() + .username("matias") + .password("{noop}examplepass") + .roles("EMPLOYEE", "TL") + .build(); + + UserDetails alejo = User.builder() + .username("alejo") + .password("{noop}examplepass") + .roles("EMPLOYEE", "TL", "ADMIN") + .build(); + + return new InMemoryUserDetailsManager(ramiro, matias, alejo); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + + http.authorizeHttpRequests(configurer -> + configurer + .requestMatchers(HttpMethod.GET, "/api/employees").hasRole("EMPLOYEE") + .requestMatchers(HttpMethod.GET, "/api/employees/**").hasRole("EMPLOYEE") + .requestMatchers(HttpMethod.POST, "/api/employees").hasRole("TL") + .requestMatchers(HttpMethod.PUT, "/api/employees").hasRole("TL") + .requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN") + ); + + http.httpBasic(Customizer.withDefaults()); + http.csrf(csrf -> csrf.disable()); + + return http.build(); + } +} From 41b00a2301ae1fd08deb552e84ff593830209e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Tue, 15 Aug 2023 23:53:19 -0300 Subject: [PATCH 07/17] mysql scripts directory added --- mysqlscripts/employee-directory.sql | 28 ++++++++++ mysqlscripts/spring-security-users.sql | 52 ++++++++++++++++++ .../security/SecurityConfig.class | Bin 0 -> 5141 bytes 3 files changed, 80 insertions(+) create mode 100644 mysqlscripts/employee-directory.sql create mode 100644 mysqlscripts/spring-security-users.sql create mode 100644 target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class diff --git a/mysqlscripts/employee-directory.sql b/mysqlscripts/employee-directory.sql new file mode 100644 index 0000000..35ba369 --- /dev/null +++ b/mysqlscripts/employee-directory.sql @@ -0,0 +1,28 @@ +CREATE DATABASE IF NOT EXISTS `employee_directory`; +USE `employee_directory`; + +-- +-- Table structure for table `employee` +-- + +DROP TABLE IF EXISTS `employee`; + +CREATE TABLE `employee` ( + `id` int NOT NULL AUTO_INCREMENT, + `first_name` varchar(45) DEFAULT NULL, + `last_name` varchar(45) DEFAULT NULL, + `email` varchar(45) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; + +-- +-- Data for table `employee` +-- + +INSERT INTO `employee` VALUES + (1,'Manuel','Miguez','manum@mail.com'), + (2,'Luca','Vinelli','lucav@mail.com'), + (3,'Iñaki','Mariño','iñakim@mail.com'), + (4,'Manfiu','Puerto','manfiudp@mail.com'), + (5,'Juani','Pucheta','juanip@mail.com'); + diff --git a/mysqlscripts/spring-security-users.sql b/mysqlscripts/spring-security-users.sql new file mode 100644 index 0000000..a9ba445 --- /dev/null +++ b/mysqlscripts/spring-security-users.sql @@ -0,0 +1,52 @@ +USE `employee_directory`; + +DROP TABLE IF EXISTS `authorities`; +DROP TABLE IF EXISTS `users`; + +-- +-- Table structure for table `users` +-- + +CREATE TABLE `users` ( + `username` varchar(50) NOT NULL, + `password` varchar(50) NOT NULL, + `enabled` tinyint NOT NULL, + PRIMARY KEY (`username`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Inserting data for table `users` +-- + +INSERT INTO `users` +VALUES +('ramiro','{noop}examplepass',1), +('matias','{noop}examplepass',1), +('alejo','{noop}examplepass',1); + + +-- +-- Table structure for table `authorities` +-- + +CREATE TABLE `authorities` ( + `username` varchar(50) NOT NULL, + `authority` varchar(50) NOT NULL, + UNIQUE KEY `authorities_idx_1` (`username`,`authority`), + CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`username`) REFERENCES `users` (`username`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Inserting data for table `authorities` +-- + +INSERT INTO `authorities` +VALUES +('ramiro','ROLE_EMPLOYEE'), +('matias','ROLE_EMPLOYEE'), +('matias','ROLE_MANAGER'), +('alejo','ROLE_EMPLOYEE'), +('alejo','ROLE_MANAGER'), +('alejo','ROLE_ADMIN'); + + diff --git a/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class b/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..23eaa5ff0122dc38d9b5039e9099c6c3eccd2fc3 GIT binary patch literal 5141 zcmcgw`*$0~75>JSy^gYp9pyn1lC&g(_>p8o3V|RXjcq|prP#Ins7p&amd5rb(yrKD zIdLeorO*~A6#9U^>6^YwdwL9qp7!u_PyeQ#exqGkvf0|k0gjJ%ckbMoxsUHYM*sfr zJO2Xk0NzZZ4ebUJCOXh5&~rsDN~IOhNSfFV zQ{as2&0Buevz_@lPgc}5*Sl)@s#x>vV96@Fp0aAb@=7X@cG<-lunCQ(lEmH`z!kG_1 z_I(1oo^V{Z`lPxpE7h{9O5fLN>^E^h>(HeMv}(z~t*g8f%Fuy1uP??xOA6u0uCjBTimbTyIIECOR!I9XYQ&19u9X zTX&~e2uHglaSET%adVfzd76348)f>YQjEs4Choz#0^5o;KX5Dd4dU+1#zuAK?0IXb zvBb+HaUU`U?l&3UjM|GEh*e)M9mfr5d)Kk9saY!uP~W;31l2+m&H{U7Em&|p3a07f z>hYTL17hrpy&LJiR>loOXVX$;w&RnyU|`V1kT%|_&8XY7mVkN94i<*hoUD}thTeV1 zns`VXZrcKt9F)FYOhMqRo*FUnh@MImeQ!<^ayka`0(Xk$0* z`;c7@lsB{>Z6}FOW86T&!~`Y<^6TzVbmNQ_Qfr>_d~1l(4%NBzmXBWEn3G^UJ*zomXwFH69Tu#!eWmb6;VGyQrZc&z} zq-X1KL`(z=HZgN9x5e`^0;%^_JeGrvB7T##lly04!*)gg^-3pK9~iGWfn8BkEYwu{ z!b%0A)+b|kW=adx^}uRLMuSQ^+-v(>Gj|F+9Uo^cg2mx4w&rcrY#b5^7y*e|U(kNns6Du%PS{ri>1J%_BCD@ME^mtr|r=V&4?4_0uG3c-_P| z@nR2NB;gmD@JkcV;rSjs&mMKeao8G`c^A}oy6r6&U<1DucsU366My!IR|TV$nvv1Zhvb4I{N<8QrP9%eW=+PaK?SPaP^OTR8J3 zB?zS+ZX@jQ+-of3# zGR{p8yp8kA7@j8OVNJO>J+O>Vy^Bjt4N~=!Pf+^1k;2)!yxIr*!o4DixGTPjXL#PT zoJ;WiHGG3#9fD-EiqwkuQOl`E0{0D^~e7$KT<*0@g bzae}s;|=@{yXeq2@O#?g5BL-Qf&>2pbc9!9 literal 0 HcmV?d00001 From a81e13231cf7068d8c29ac8e3fc3f919d54ef9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Tue, 15 Aug 2023 23:57:51 -0300 Subject: [PATCH 08/17] Jdbc implemented on configuration, hard coded sql user builders commented --- .../security/SecurityConfig.java | 51 ++++++++++-------- .../security/SecurityConfig.class | Bin 5141 -> 4238 bytes 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java index 6814036..43e6afc 100644 --- a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java +++ b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java @@ -9,35 +9,44 @@ import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.provisioning.JdbcUserDetailsManager; +import org.springframework.security.provisioning.UserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import javax.sql.DataSource; + @Configuration public class SecurityConfig { @Bean - public InMemoryUserDetailsManager UserDetailsManager() { - - UserDetails ramiro = User.builder() - .username("ramiro") - .password("{noop}examplepass") - .roles("EMPLOYEE") - .build(); - - UserDetails matias = User.builder() - .username("matias") - .password("{noop}examplepass") - .roles("EMPLOYEE", "TL") - .build(); - - UserDetails alejo = User.builder() - .username("alejo") - .password("{noop}examplepass") - .roles("EMPLOYEE", "TL", "ADMIN") - .build(); - - return new InMemoryUserDetailsManager(ramiro, matias, alejo); + public UserDetailsManager userDetailsManager (DataSource dataSource){ + return new JdbcUserDetailsManager(dataSource); } +// @Bean +// public InMemoryUserDetailsManager UserDetailsManager() { +// +// UserDetails ramiro = User.builder() +// .username("ramiro") +// .password("{noop}examplepass") +// .roles("EMPLOYEE") +// .build(); +// +// UserDetails matias = User.builder() +// .username("matias") +// .password("{noop}examplepass") +// .roles("EMPLOYEE", "TL") +// .build(); +// +// UserDetails alejo = User.builder() +// .username("alejo") +// .password("{noop}examplepass") +// .roles("EMPLOYEE", "TL", "ADMIN") +// .build(); +// +// return new InMemoryUserDetailsManager(ramiro, matias, alejo); +// } + @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { diff --git a/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class b/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class index 23eaa5ff0122dc38d9b5039e9099c6c3eccd2fc3..c2cbe0beb34ad47782de0341355ea07a25d9c208 100644 GIT binary patch delta 1453 zcmZuxTUQ%Z6#h<_WRl^KOoBjzEw+kE6J^l00;NE?q!vsdl|YOa+98=jXqbddKguz9!e8J&aJk$kiA_Kr=Ipb-z0cnJe0!hyuJ7&%<&S^% zeg`m$d*3RWONN`_yv-cP>^~iC7iKdn=|#&ZP8%gXo3moNsjnJE1u_&4Ct4YTebIG& zTi?;F&73x^m-L1FRxxdioLmY})HV(;eD?P(Q(iv;GTJ$wKnKG``;ydatI|Vn7mmmX za&*JT&`)r`?Q#0g`Eiuvm~i#1l}d$4-O8o|U}#g|$8nAm!X%}w;#C1W!_kXp8JsIy z*<8k+a|Wg78BSNPaoZX6o)v94Y#!DP8ye@RtbR-%{MBGRaLle`nnK>Ct_K@d(c|n1E=Iy0P&x*c%;QEgbRIqc#9+)Qt>rUuy{K;(C8KEV-cTl4SC*l@!EIzGZ4^q` zyt(^VtL5-+D|i<>GOlyHhxd0)uf*aXGIZ36s$s-k8Uvp(O`|xK(=E%eWZY(0-q#DCy3D?^O*JIlW$3Xt)gF6K<>f^*M@fpHp5Gv+!Vlp2 zk(A~DUDW`c!l?{TJp%b-8J8*26>@h{`6P7uMA8+K3~6K_Ra0c>tVq!t-lIZLftn2e zip~n2OcK%~kf)O23Z8z1=Nj1qbQ(AVF@OP#<0vM|jZ)}k)$T%JVc;qyTqSpjFTICqO^7G1`1V MEPRQt@eP9i0`0&Pn*aa+ literal 5141 zcmcgw`*$0~75>JSy^gYp9pyn1lC&g(_>p8o3V|RXjcq|prP#Ins7p&amd5rb(yrKD zIdLeorO*~A6#9U^>6^YwdwL9qp7!u_PyeQ#exqGkvf0|k0gjJ%ckbMoxsUHYM*sfr zJO2Xk0NzZZ4ebUJCOXh5&~rsDN~IOhNSfFV zQ{as2&0Buevz_@lPgc}5*Sl)@s#x>vV96@Fp0aAb@=7X@cG<-lunCQ(lEmH`z!kG_1 z_I(1oo^V{Z`lPxpE7h{9O5fLN>^E^h>(HeMv}(z~t*g8f%Fuy1uP??xOA6u0uCjBTimbTyIIECOR!I9XYQ&19u9X zTX&~e2uHglaSET%adVfzd76348)f>YQjEs4Choz#0^5o;KX5Dd4dU+1#zuAK?0IXb zvBb+HaUU`U?l&3UjM|GEh*e)M9mfr5d)Kk9saY!uP~W;31l2+m&H{U7Em&|p3a07f z>hYTL17hrpy&LJiR>loOXVX$;w&RnyU|`V1kT%|_&8XY7mVkN94i<*hoUD}thTeV1 zns`VXZrcKt9F)FYOhMqRo*FUnh@MImeQ!<^ayka`0(Xk$0* z`;c7@lsB{>Z6}FOW86T&!~`Y<^6TzVbmNQ_Qfr>_d~1l(4%NBzmXBWEn3G^UJ*zomXwFH69Tu#!eWmb6;VGyQrZc&z} zq-X1KL`(z=HZgN9x5e`^0;%^_JeGrvB7T##lly04!*)gg^-3pK9~iGWfn8BkEYwu{ z!b%0A)+b|kW=adx^}uRLMuSQ^+-v(>Gj|F+9Uo^cg2mx4w&rcrY#b5^7y*e|U(kNns6Du%PS{ri>1J%_BCD@ME^mtr|r=V&4?4_0uG3c-_P| z@nR2NB;gmD@JkcV;rSjs&mMKeao8G`c^A}oy6r6&U<1DucsU366My!IR|TV$nvv1Zhvb4I{N<8QrP9%eW=+PaK?SPaP^OTR8J3 zB?zS+ZX@jQ+-of3# zGR{p8yp8kA7@j8OVNJO>J+O>Vy^Bjt4N~=!Pf+^1k;2)!yxIr*!o4DixGTPjXL#PT zoJ;WiHGG3#9fD-EiqwkuQOl`E0{0D^~e7$KT<*0@g bzae}s;|=@{yXeq2@O#?g5BL-Qf&>2pbc9!9 From 7d71cc94cb07dc6998c70227b8c0df60a3df966f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Wed, 16 Aug 2023 10:45:35 -0300 Subject: [PATCH 09/17] spring security sql script with bcrypted passwords --- mysqlscripts/spring-security-users-bcrypt.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 mysqlscripts/spring-security-users-bcrypt.sql diff --git a/mysqlscripts/spring-security-users-bcrypt.sql b/mysqlscripts/spring-security-users-bcrypt.sql new file mode 100644 index 0000000..3228fe1 --- /dev/null +++ b/mysqlscripts/spring-security-users-bcrypt.sql @@ -0,0 +1 @@ +SELECT * FROM employee_directory.users; \ No newline at end of file From aafa3285d228996e3a488411fcf17dc1f2ceb531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Wed, 16 Aug 2023 11:14:03 -0300 Subject: [PATCH 10/17] bcrypted passwords tested, working fine, commented code deleted, custom tables to fix --- .../security/SecurityConfig.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java index 43e6afc..80b1647 100644 --- a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java +++ b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java @@ -23,29 +23,6 @@ public UserDetailsManager userDetailsManager (DataSource dataSource){ return new JdbcUserDetailsManager(dataSource); } -// @Bean -// public InMemoryUserDetailsManager UserDetailsManager() { -// -// UserDetails ramiro = User.builder() -// .username("ramiro") -// .password("{noop}examplepass") -// .roles("EMPLOYEE") -// .build(); -// -// UserDetails matias = User.builder() -// .username("matias") -// .password("{noop}examplepass") -// .roles("EMPLOYEE", "TL") -// .build(); -// -// UserDetails alejo = User.builder() -// .username("alejo") -// .password("{noop}examplepass") -// .roles("EMPLOYEE", "TL", "ADMIN") -// .build(); -// -// return new InMemoryUserDetailsManager(ramiro, matias, alejo); -// } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { From 54dcd6ca2d7ca4a6249ce77a963eef87010c164b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Wed, 16 Aug 2023 11:21:46 -0300 Subject: [PATCH 11/17] sql scripts updated, custom tables created --- mysqlscripts/employee-directory.sql | 6 --- mysqlscripts/spring-security-finished.sql | 36 +++++++++++++++++ mysqlscripts/spring-security-users-bcrypt.sql | 37 +++++++++++++++++- mysqlscripts/spring-security-users.sql | 13 ------ .../security/SecurityConfig.class | Bin 4238 -> 4238 bytes 5 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 mysqlscripts/spring-security-finished.sql diff --git a/mysqlscripts/employee-directory.sql b/mysqlscripts/employee-directory.sql index 35ba369..ee866ba 100644 --- a/mysqlscripts/employee-directory.sql +++ b/mysqlscripts/employee-directory.sql @@ -1,9 +1,6 @@ CREATE DATABASE IF NOT EXISTS `employee_directory`; USE `employee_directory`; --- --- Table structure for table `employee` --- DROP TABLE IF EXISTS `employee`; @@ -15,9 +12,6 @@ CREATE TABLE `employee` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; --- --- Data for table `employee` --- INSERT INTO `employee` VALUES (1,'Manuel','Miguez','manum@mail.com'), diff --git a/mysqlscripts/spring-security-finished.sql b/mysqlscripts/spring-security-finished.sql new file mode 100644 index 0000000..16597f3 --- /dev/null +++ b/mysqlscripts/spring-security-finished.sql @@ -0,0 +1,36 @@ +USE `employee_directory`; + +DROP TABLE IF EXISTS `roles`; +DROP TABLE IF EXISTS `members`; + + +CREATE TABLE `members` ( + `user` varchar(50) NOT NULL, + `psw` char(68) NOT NULL, + `active` tinyint NOT NULL, + PRIMARY KEY (`user`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO `members` +VALUES +('ramiro','{bcrypt}$2a$10$S7GTZIc/KfegnP9H4GNaCOxHkvu0M32H7f9wg/lHl/c97VQtIoVvm',1), +('matias','{bcrypt}$2a$10$DWG0SGnfxqDIjx.LrywatevHjod2EbepV0W3t5d1aOoRLjSQuvszS',1), +('alejo','{bcrypt}$2a$10$0tqmRxOQufHIrIuQWNHa6.M4ei4LbE4NhN6gfUEOOnxpkbzLABGc6',1); + + +CREATE TABLE `roles` ( + `user` varchar(50) NOT NULL, + `role` varchar(50) NOT NULL, + UNIQUE KEY `authorities5_idx_1` (`user`,`role`), + CONSTRAINT `authorities5_ibfk_1` FOREIGN KEY (`user`) REFERENCES `members` (`user`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +INSERT INTO `roles` +VALUES +('john','ROLE_EMPLOYEE'), +('mary','ROLE_EMPLOYEE'), +('mary','ROLE_MANAGER'), +('susan','ROLE_EMPLOYEE'), +('susan','ROLE_MANAGER'), +('susan','ROLE_ADMIN'); diff --git a/mysqlscripts/spring-security-users-bcrypt.sql b/mysqlscripts/spring-security-users-bcrypt.sql index 3228fe1..e6002cd 100644 --- a/mysqlscripts/spring-security-users-bcrypt.sql +++ b/mysqlscripts/spring-security-users-bcrypt.sql @@ -1 +1,36 @@ -SELECT * FROM employee_directory.users; \ No newline at end of file +USE `employee_directory`; + +DROP TABLE IF EXISTS `authorities`; +DROP TABLE IF EXISTS `users`; + + +CREATE TABLE `users` ( + `username` varchar(50) NOT NULL, + `password` char(68) NOT NULL, + `enabled` tinyint NOT NULL, + PRIMARY KEY (`username`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO `users` +VALUES +('ramiro','{bcrypt}$2a$10$S7GTZIc/KfegnP9H4GNaCOxHkvu0M32H7f9wg/lHl/c97VQtIoVvm',1), +('matias','{bcrypt}$2a$10$DWG0SGnfxqDIjx.LrywatevHjod2EbepV0W3t5d1aOoRLjSQuvszS',1), +('alejo','{bcrypt}$2a$10$0tqmRxOQufHIrIuQWNHa6.M4ei4LbE4NhN6gfUEOOnxpkbzLABGc6',1); + + +CREATE TABLE `authorities` ( + `username` varchar(50) NOT NULL, + `authority` varchar(50) NOT NULL, + UNIQUE KEY `authorities4_idx_1` (`username`,`authority`), + CONSTRAINT `authorities4_ibfk_1` FOREIGN KEY (`username`) REFERENCES `users` (`username`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +INSERT INTO `authorities` +VALUES +('ramiro','ROLE_EMPLOYEE'), +('matias','ROLE_EMPLOYEE'), +('matias','ROLE_MANAGER'), +('alejo','ROLE_EMPLOYEE'), +('alejo','ROLE_MANAGER'), +('alejo','ROLE_ADMIN'); \ No newline at end of file diff --git a/mysqlscripts/spring-security-users.sql b/mysqlscripts/spring-security-users.sql index a9ba445..47363d0 100644 --- a/mysqlscripts/spring-security-users.sql +++ b/mysqlscripts/spring-security-users.sql @@ -3,9 +3,6 @@ USE `employee_directory`; DROP TABLE IF EXISTS `authorities`; DROP TABLE IF EXISTS `users`; --- --- Table structure for table `users` --- CREATE TABLE `users` ( `username` varchar(50) NOT NULL, @@ -14,9 +11,6 @@ CREATE TABLE `users` ( PRIMARY KEY (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- --- Inserting data for table `users` --- INSERT INTO `users` VALUES @@ -25,10 +19,6 @@ VALUES ('alejo','{noop}examplepass',1); --- --- Table structure for table `authorities` --- - CREATE TABLE `authorities` ( `username` varchar(50) NOT NULL, `authority` varchar(50) NOT NULL, @@ -36,9 +26,6 @@ CREATE TABLE `authorities` ( CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- --- Inserting data for table `authorities` --- INSERT INTO `authorities` VALUES diff --git a/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class b/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class index c2cbe0beb34ad47782de0341355ea07a25d9c208..b885ae421c9778faacd32982ae8678df3b146da4 100644 GIT binary patch delta 57 zcmeBE>{HzEiH}!~fr~+%L5M+vL54wV@_)VzMvciC{A)#37{HzEiI3Nmfs4V8L5RVgL59I`@_)VzM*GPb{A)$68F(4Y8B`c77_1pA8G;zB N7%~~GCu<3$004i{3=04N From 33dc396eb19208f906cb8fdd0e7901de6914105e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Wed, 16 Aug 2023 11:32:58 -0300 Subject: [PATCH 12/17] sql scripts updated, spring security configuration updated, custom tables set --- mysqlscripts/spring-security-finished.sql | 12 ++++++------ .../security/SecurityConfig.java | 13 +++++++++---- .../security/SecurityConfig.class | Bin 4238 -> 4581 bytes 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/mysqlscripts/spring-security-finished.sql b/mysqlscripts/spring-security-finished.sql index 16597f3..959a855 100644 --- a/mysqlscripts/spring-security-finished.sql +++ b/mysqlscripts/spring-security-finished.sql @@ -28,9 +28,9 @@ CREATE TABLE `roles` ( INSERT INTO `roles` VALUES -('john','ROLE_EMPLOYEE'), -('mary','ROLE_EMPLOYEE'), -('mary','ROLE_MANAGER'), -('susan','ROLE_EMPLOYEE'), -('susan','ROLE_MANAGER'), -('susan','ROLE_ADMIN'); +('ramiro','ROLE_EMPLOYEE'), +('matias','ROLE_EMPLOYEE'), +('matias','ROLE_MANAGER'), +('alejo','ROLE_EMPLOYEE'), +('alejo','ROLE_MANAGER'), +('alejo','ROLE_ADMIN'); diff --git a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java index 80b1647..cd5fe8b 100644 --- a/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java +++ b/src/main/java/com/manumiguezz/crudapplication/security/SecurityConfig.java @@ -6,9 +6,6 @@ import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.provisioning.UserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @@ -20,7 +17,15 @@ public class SecurityConfig { @Bean public UserDetailsManager userDetailsManager (DataSource dataSource){ - return new JdbcUserDetailsManager(dataSource); + JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource); + + jdbcUserDetailsManager + .setUsersByUsernameQuery("select user, psw, active from members where user=?"); + + jdbcUserDetailsManager + .setAuthoritiesByUsernameQuery("select user, role from roles where user=?"); + + return jdbcUserDetailsManager; } diff --git a/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class b/target/classes/com/manumiguezz/crudapplication/security/SecurityConfig.class index b885ae421c9778faacd32982ae8678df3b146da4..2b7ca08a77c33513aaf9cc568d669fb0e66f8e77 100644 GIT binary patch delta 1521 zcmZWpTUQ%Z6#h;!WRmd^V9KSWP*X`;NCLr%T8k~^5(Om%%B^T^8NvXANx+!^#cI=f z$7(fBz0~T9%V%%6f(tJT9`#q~gRlMsm-~d2P<)uP&-wN~``hO``^>E)e>W(9{JZ%Z zfYbOgtK7}FQOa<_(i3_-?O(EVGwffqR>FQQo;H?s|BShi^e6S?lx|x7l{wwi^FgOO z6v!y!C`ScDjiskYX{*(>DojdC>O)Jqxyn%0*gvl=YmtPOnvD#nO(Qki-ZbXM0fweL z=Y@Nu=0c*tCT9QVs^X{?T=m4&xs;w;FpadK?`Kr$Ut1!$Adg2yujk zONv|Oi~w3VB4}kOnOZUu(+ri3_Fqz!bb_HRyIpU8?Wpy(;ZYfnaXgNb46&U8%IrTC zZY$1N?2g=2!_IpJ^)j*f`+MUEH5+SL>7kB&s$xJ(jt z_Qd+m$>8BHHY_g z1#jR@8EnKlx}t> zG|SR086PuTD#{VEjnWS34#QFV2CuRIDV6O~F1uvhWjI`b4rC_bpq>Iss1HiuqH&5= z5wc96!40tQY2rYfM&Sm%iD?@7P5^Yw(28Leb8zN28)Th?)%*;3BD4WdEUfYzykS+% zp)&j(xpva|;L6aV5+3S(jvACvXRGj`irPOYI4C0w%oCRfUc86|rAbm$2_qOt z(I*OAAj`0bmmuZKnWivt#z1J35+H{|j-G zLeD})GgTDH*HpceY`3NWOjtyirf7-m(!H8Y0`}BYu83=+0HJRySs|q>6U^a}@%;)n z?@`!A{Hr9oBHEy^{l~&hEC+wU6Vk8fm~g6{!#Q+sp-+7_hgcCFx*s0i7oAbZ^5GZu z;RX2l0=%2$5=HMRmu`?w(S%a^(*$q~?KqC}^oubFD>lh8UcsvrC*c~64rF$9xqgO# r8}tcPU!&Vz!%f^O%s#+Ju*v5mya%`O2`cC@-^Qn;!e{s#U!e9s%!V-4 delta 1170 zcmZvcTXR!Y6vux%Imv0y?4G76ZK0shHcCjOLBLC`ZS5sWX+ncd3Go6AA<&i(VpFRq z5WIo)f|ui)FMa@rQR_qpM~7$M{05FQy!z^!x=zfr(eYvLwbp;#{(J3x&b@(Keb&!^ z-uVd_;p0!N&#j=SZ5o?)=Zc!NI|!O|YPQj(IO6YLj(dmfeMC&6 znupl0NJ`bDbI+T#V;nGfSaXm=iUEPQISa;^dc^s{=<0t=VaIairC8x&xp?Vvp-{0H z;t7*s&6A8M)+J%g`O<&XS@7j0jbZ}`JA;0+dtA{HPo@&H*?8Pylu6ALac9PV`}8x4 zj(?YqMIx=lnARM1xfrS0xpWH&g(sbG9mh1YuEU#}PrLSU&9koUpNc2q>39oig>QT+ zIepCJ#KuW;Ty6Z(GN;ti#*DS@vDYkK;Z>8%n%8)J<2P-n)Kx`SII)~t%f*Vh()rlz zndL%$b$H*2c0W~%d9G_NQVLKK;4K$;TeHlC02dT`x>PExOcryMN}*!%uHsbV@VlMQ z>@nj5CG#)0^*F!V0d>py%iiBPk4GK=_~hDr_+`&HW9{A5lY+Sxbdr@_*L5Gy@w`}y z7kCjb8PP{Xx;0vVz|2O!qxCB>JZu%{sTb(}C#X?C!a2ohDYPKbJ|QY1C(G@52C5?R zoW-cOI4iksi%|5A5TQmO6aAj<8ap$B-0vd0GtnCTcX@EDdr-0wuf<-1gxN);iAiXa zNr(dHq~CdoHbgE8r)r&4L69a=0n44VM7YO3AkrO=KT;!{`C7E*Gl!do=9llF2$C%q z*U0|1G2FGtHw+p-ayaV^J~~(9@waxZe9Eumnci1!Atd%u58YwBKE2*_kLfNr*MU9ywT9! c Date: Thu, 17 Aug 2023 19:45:31 -0300 Subject: [PATCH 13/17] assets folder added, data base preview added --- src/main/assets/DatabaseFinalPreview.png | Bin 0 -> 20315 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/assets/DatabaseFinalPreview.png diff --git a/src/main/assets/DatabaseFinalPreview.png b/src/main/assets/DatabaseFinalPreview.png new file mode 100644 index 0000000000000000000000000000000000000000..9de952d0ef7ae2bd0524d182abc1f201e11e08f0 GIT binary patch literal 20315 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 eCbW0;+pd!`ae)@vn%V#mkL859ty#GVJn~O0o Date: Thu, 17 Aug 2023 19:46:46 -0300 Subject: [PATCH 14/17] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4d53534..59b5e34 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # BasicSpringBootAPI Efficient REST API crafted using Core Java and Spring Boot, enabling smooth CRUD operations on an employee database. + +# Database Preview +![DatabaseFinalPreview](https://github.com/manumiguezz/CompanySpringBootRESTAPI/assets/111899370/0caf9d83-1459-478e-b64d-5bac3cd3af9d) From 549bf0e7bb16b75f162931137d926087ac239baa Mon Sep 17 00:00:00 2001 From: Manumiguezz Date: Thu, 17 Aug 2023 20:09:20 -0300 Subject: [PATCH 15/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 59b5e34..658fac3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BasicSpringBootAPI -Efficient REST API crafted using Core Java and Spring Boot, enabling smooth CRUD operations on an employee database. +Efficient REST API crafted using Core Java and Spring Boot, enabling smooth CRUD operations on an employee database, that includes the incorporation of a Spring Security layer, using bcrypt-hashed passwords, and executed through the adept utilization of JDBC technology. # Database Preview ![DatabaseFinalPreview](https://github.com/manumiguezz/CompanySpringBootRESTAPI/assets/111899370/0caf9d83-1459-478e-b64d-5bac3cd3af9d) From 58a7f9b909ea7bc960cd14573eec0d9d60dd4237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Miguez=20Laur=C3=ADa?= Date: Thu, 17 Aug 2023 20:11:01 -0300 Subject: [PATCH 16/17] database preview asset fixed --- src/main/assets/DatabaseFinalPreview.png | Bin 20315 -> 18820 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/assets/DatabaseFinalPreview.png b/src/main/assets/DatabaseFinalPreview.png index 9de952d0ef7ae2bd0524d182abc1f201e11e08f0..043759d14ad9e29a0397e83d4e45dee8e6547ca4 100644 GIT binary patch literal 18820 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 literal 20315 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 eCbW0;+pd!`ae)@vn%V#mkL859ty#GVJn~O0o Date: Thu, 17 Aug 2023 20:12:05 -0300 Subject: [PATCH 17/17] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 658fac3..5b8dfa5 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,5 @@ Efficient REST API crafted using Core Java and Spring Boot, enabling smooth CRUD operations on an employee database, that includes the incorporation of a Spring Security layer, using bcrypt-hashed passwords, and executed through the adept utilization of JDBC technology. # Database Preview -![DatabaseFinalPreview](https://github.com/manumiguezz/CompanySpringBootRESTAPI/assets/111899370/0caf9d83-1459-478e-b64d-5bac3cd3af9d) + +![DatabaseFinalPreview](https://github.com/manumiguezz/CompanySpringBootRESTAPI/assets/111899370/a97b153a-3a62-447e-99fb-258f90be4019)