From 8fd234b1a949efc20d5e09105a954940fb807345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=B5=20Tr=E1=BA=A7n=20Minh=20Qu=C3=A2n?= Date: Mon, 27 Sep 2021 15:40:54 +0700 Subject: [PATCH 1/2] refactor: make some changes in the controller, service and repository of the booking module to make the code cleaner --- .../example/controller/BookingController.java | 38 +++++------------- .../example/repository/BookingRepository.java | 3 +- .../org/example/service/BookingService.java | 31 ++++++++------ .../controller/BookingController.class | Bin 5268 -> 4158 bytes .../repository/BookingRepository.class | Bin 599 -> 462 bytes .../org/example/service/BookingService.class | Bin 2240 -> 3890 bytes 6 files changed, 29 insertions(+), 43 deletions(-) diff --git a/booking/src/main/java/org/example/controller/BookingController.java b/booking/src/main/java/org/example/controller/BookingController.java index 10a7e4d..2bab730 100644 --- a/booking/src/main/java/org/example/controller/BookingController.java +++ b/booking/src/main/java/org/example/controller/BookingController.java @@ -28,21 +28,13 @@ public ResponseEntity> getAllBookings() { @GetMapping("/{id}") public ResponseEntity getBookingById(@PathVariable("id") Long id) { - Optional booking = bookingService.getBookingById(id); - if (booking.isEmpty()) { - throw new NotFoundException(); - } - return new ResponseEntity<>(booking.get(), HttpStatus.OK); + return new ResponseEntity<>(bookingService.getBookingById(id), HttpStatus.OK); } @PostMapping public ResponseEntity addNewBooking( @RequestParam("roomId") Long roomId, @RequestParam("customerName") String customerName) { - List bookedRooms = bookingService.getBookedRooms(); - if (bookedRooms.contains(roomId)) { - throw new RoomUnavailableException(); - } LocalDate today = LocalDate.now(); Booking booking = new Booking(roomId, customerName, today, null, null); return new ResponseEntity<>(bookingService.addNewBooking(booking), HttpStatus.CREATED); @@ -54,13 +46,10 @@ public ResponseEntity checkin( @RequestParam("year") int year, @RequestParam("month") int month, @RequestParam("day") int day) { - Optional booking = bookingService.getBookingById(id); - if (booking.isEmpty()) { - throw new NotFoundException(); - } + Booking booking = bookingService.getBookingById(id); LocalDate checkinDate = LocalDate.of(year, month, day); - booking.get().setCheckinDate(checkinDate); - return new ResponseEntity<>(bookingService.updateBooking(booking.get()), HttpStatus.OK); + booking.setCheckinDate(checkinDate); + return new ResponseEntity<>(bookingService.updateBooking(booking), HttpStatus.OK); } @PutMapping("/checkout/{id}") @@ -69,24 +58,15 @@ public ResponseEntity checkout( @RequestParam("year") int year, @RequestParam("month") int month, @RequestParam("day") int day) { - Optional booking = bookingService.getBookingById(id); - if (booking.isEmpty()) { - throw new NotFoundException(); - } + Booking booking = bookingService.getBookingById(id); LocalDate checkoutDate = LocalDate.of(year, month, day); - booking.get().setCheckoutDate(checkoutDate); - return new ResponseEntity<>(bookingService.updateBooking(booking.get()), HttpStatus.OK); + booking.setCheckoutDate(checkoutDate); + return new ResponseEntity<>(bookingService.updateBooking(booking), HttpStatus.OK); } @DeleteMapping("/{id}") public ResponseEntity> deleteBooking(@PathVariable("id") Long id) { - Optional booking = bookingService.getBookingById(id); - if (booking.isEmpty()) { - throw new NotFoundException(); - } - bookingService.deleteBookingById(id); - Map result = new HashMap<>(); - result.put("Message: ", "Deleted Successfully"); - return new ResponseEntity<>(result, HttpStatus.OK); + Booking booking = bookingService.getBookingById(id); + return new ResponseEntity<>(bookingService.deleteBooking(booking), HttpStatus.OK); } } diff --git a/booking/src/main/java/org/example/repository/BookingRepository.java b/booking/src/main/java/org/example/repository/BookingRepository.java index 4926a94..e8c0123 100644 --- a/booking/src/main/java/org/example/repository/BookingRepository.java +++ b/booking/src/main/java/org/example/repository/BookingRepository.java @@ -7,6 +7,5 @@ import java.util.List; public interface BookingRepository extends JpaRepository { - @Query("SELECT b.roomId FROM Booking b WHERE b.checkoutDate IS NULL") - List findBookedRooms(); + List findBookingsByCheckoutDateIsNull(); } diff --git a/booking/src/main/java/org/example/service/BookingService.java b/booking/src/main/java/org/example/service/BookingService.java index a0ac5b1..4abb21d 100644 --- a/booking/src/main/java/org/example/service/BookingService.java +++ b/booking/src/main/java/org/example/service/BookingService.java @@ -2,13 +2,13 @@ import lombok.AllArgsConstructor; import org.example.exception.NotFoundException; +import org.example.exception.RoomUnavailableException; import org.example.model.Booking; import org.example.repository.BookingRepository; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Optional; +import java.util.*; @Service @AllArgsConstructor @@ -19,19 +19,23 @@ public List getAllBookings() { return bookingRepository.findAll(Sort.by("id")); } - public Optional getBookingById(Long id) { - try { - return bookingRepository.findById(id); - } catch (Exception e) { + public Booking getBookingById(Long id) { + Optional booking = bookingRepository.findById(id); + if (booking.isEmpty()) { throw new NotFoundException(); } - } - - public List getBookedRooms() { - return bookingRepository.findBookedRooms(); + return booking.get(); } public Booking addNewBooking(Booking booking) { + List bookings = bookingRepository.findBookingsByCheckoutDateIsNull(); + List bookedRooms = new ArrayList<>(); + bookings.forEach((bookingInList) -> { + bookedRooms.add(bookingInList.getRoomId()); + }); + if (bookedRooms.contains(booking.getRoomId())) { + throw new RoomUnavailableException(); + } return bookingRepository.save(booking); } @@ -39,7 +43,10 @@ public Booking updateBooking(Booking booking) { return bookingRepository.save(booking); } - public void deleteBookingById(Long id) { - bookingRepository.deleteById(id); + public Map deleteBooking(Booking booking) { + bookingRepository.delete(booking); + Map result = new HashMap<>(); + result.put("Message: ", "Deleted Successfully"); + return result; } } diff --git a/booking/target/classes/org/example/controller/BookingController.class b/booking/target/classes/org/example/controller/BookingController.class index a31649c0a5941cee4627aa09163e6230df510466..160d5858765656a16c0cccce98a3798a2f2bdc32 100644 GIT binary patch literal 4158 zcmb_f3sVzU6#i~Vh{OdoJ`lueeG#5p6(1#t4?v~zDp=~HwcR8avY2G!W&<*v&h)4B zC$vtBPMzrw=#T33yLUG)Pz=^#LiXN0_uTV+=R4=#{PXW$e*+l9W)vZTUdLTEOGVc% ztgg6LUT!$icX;Gwl>S*U9Ci zYu<63=X5nuoe}6r`EyIsUANOx;M`38;*vjISs7R*V~AmY6o!FzbO@aJ@DlE{D!tpe zTo6M^AfD)(S+mwHv+UV9bH*-t$u=Csp(x@84&#Wx+4sV~PY#wm%PZ4QX#Rn~c^&pU zsjAsBZh>P4I&oZ}b<8f<-nhVM!Ve>76;{pp)S66t$)>#ZEh`?n4V*xak1qgsXLC9u zFjVh%#wn~O`x>~-I~kd)Fw4+B!>K4v8~7Y&1P*IvJUcJV87FP!CM}Q2X(>1x0-Y7& z8eb=)I496mpNobqVmONn3Vg3XW=Cvw94vWCa7lk=+aAqN`t0->=*NISyOqhz$&G*@ zf$ND~xY&&+C6OTm!%82~iN&eg52q#-cV8H|h)Yz1vm(%)n4X>v)U^$OVqwI<6la?6i6|yj_ND|5>bG@zr7{wI%K`&b#(Qg~v1KF$!V^>=qn@z~ za;}_DN%x_Z%5f&HCAVz3wi*YMVJ~a5+WH&vwp(-I4sA>JYJpYi(&@A2V;idzUC5YL)z-WxJu+TY z1t5^zQ6_ugH)OL59IV5ln*gU~rI&Rw3zll>gvaDT&rk~tQ+s<^szqBv(P0&BbN!+j z)G)6}VV;WMjV`Wky?l!DxgB@Wf_wT79p)H_zlC_*{|8#O(Dn)kUgPL*oDJbV|F>$3 zZcOvp@U8I`9&j|HZDuhSSk3dBZ37F4Xz%y9dx&#~E8YjT(DiQjr?mTHzIouD3-L7; z>2irqB7%d;o)7h&9eg#<&o@sYN?69Xd~dMQ@JLOTXwRbmVn9zZa_@1hPUceI_sIq&C?+7D|Gx#3Q zxHgU>_yIq1M!{$c(G)bQK(VUyr8uV`bcPsr+K2F@_DGP(Kn7@jrN1bRhgH@TucMKk zlSjjEV2-wSMY>wIaJh;qvW08gX^(R~cpHr25^27SZj5MT_kFKbWWzxUxD!^esuMJf zET0rB!?5`jrk8UXV}!m=V2!w2HQGaAowOC2X8E!C@kR5zn!ua_suP&k=!cXd>k=3c zu~H)oPgJm1ZYObfDVMIKNe+i1ok5 y?f!v3(egV-_3h_~4#)2gv1&Lmigh1%3Hn2nKYK#(^wP2pBhK+U#~am9Uj7G46+DCh literal 5268 zcmcIoXR+N7Ifx9PrbpV~YvPU`1r`nCPo-_W1Yr%&H|XC#fli?Z|saOcjsXL-+i&bh-s z|NGa!0T{v`G&Betbc;)dS18)f(#4{gw^rTaWn!uAxbX zhGv13JZ4=n^M#ycWL(EDy1ATHG)7$aGF6RMb_BL8277Z>amCJ90uN3_4|~CO`D7@S zP9ljG4Z4n2Y!P_i?nh{8$?}iqa-k2NKwGMN>XNx)8YSP(8B@0BrxVzQ?Hby2?7&We z1Gf!-oEXgcreC6-hEq=qJfz&dB~(>e`Yo_q#~$nzXd1E|+aDGfOa*S_OlQeBwRp+O z`02W|b5`7AG&q) zpqI}~iNMZs9-;tf=oe^@<~8qTtz4N1GH^r3!!r9au`+NgJL|f6uLYmMBN`snaTrJV zwi=I2u|TsVq-i_M+^#4>A@VZ3#{>qVrmNve3uhgY#?G0GIV%$7QFJAd#*l_5bPVH| zzz${ExAT@U3DYOP8y$C5U{5*b+Sg1*AC613Mg+1^?^OOGJel)lQKo~P4NB_Y z3>b7m#~4luw3^xMjI|n)NZ_$lO)b_WfLw|qRQpbr(YTHYSwq_B?AY-$V<#jyPwSY% zG%LovDA19bn3xC|xgh|F!YLi6@mc22v;5IzE5pVS0Jt}VWy6^ulsO$|R4AoFmT-rm zNPY7<&Pjb+%lh1sFBM8AE$Da#7X-GGVOHf-P(?d7Wubds!{;bmCDypqWPKUeYOfk z>v^+i%ja-2<}ceUt)3cs+-U~TLSoKda@b6ZRQg=~z70i?nDDKl^kS&SZY?c`)5A2@ zK3n3<%3JfcXY;^u$8p)n*$e6Qqql@*)mk(bZ6|A(6unhWz6=%UotmVIH?lTmG_} zJ#EUlPjHFO`Hvsw-K@t~%v_1tj~g%8*_SxcYm-#*q9$8M>dw|_(_b$0l)z1I3M7Jl z*jYbHg)|j87Uam)GbPV=^Hy<&pveNM)?TPqphc!NoK=;)SFa$%z<0AINA0fQ^oBks zaL*kmPUIrFmjf?aB#KzF1}=S?0NgFNhwD$1>qV-n{`AgT&zCIES1e(4S|*qm0>hi) zR5Pdk+KjDPW>G*)FfDoB8`!8DRdQNF8^KJv@QLi)4Z!-l(&hI{QT8$~IZ9EI?M*^L^Y~GK({LGLZbOstj z52zcfxI(K5%B8<^?u{Q!p=pn^Nf;2!_*eGCr9ZlZ6Y zx34`W#0@+-7%#)z9$&}kdw41YItaN#Y3!k^y-ZghIxs*04E}ytg+3futb{&-*Hq~A z0-Yvi9KcQj^A`Os0~1KSO{oen9U4EXBru5vDh1V*!TDw- zyWirT1Z7VHk@$81%4^l->s)>Z-wpBkH!W)vo-C(+FfL<`CjZ|1cE#Su^QRS*l_y~x<2hy_&I9#d4hN>$hRbDcjyU3|Ynt9K<>idH{R z2=>dOi_j_r^J*2$Yt`j-E`RumaXni%uH!^vg1Al+*C}E#O=RL`~pG*vnGB*SK_EjL+> Yu{Yq?>gaEj8*P04EuVi^apm{_1Egzw6aWAK diff --git a/booking/target/classes/org/example/repository/BookingRepository.class b/booking/target/classes/org/example/repository/BookingRepository.class index 7bb37506ac035498ed4c6d9176da8a274621a8d2..719cdfc1531f22c2959646cbaac6f6ab1e916998 100644 GIT binary patch delta 136 zcmcc4a*mnn)W2Q(7#J9A82Bb~H7Y8kW#*+g<>zN-=A{=qRXS&+CTHiDmbfIAq#sUzDz&T9KGrkdvyPo1c=JqYpL3+Rl1% ZIpY>-Mg~rxHB1a#Kn!7VGw^^#cmcV^C*S}8 delta 236 zcmX@de4T~s)W2Q(7#J9A7=$KrH45;jW#*+g<>zOorUd2Z=N3;~qwJ!hq3M&ASeB?? zT9TQg?~_?vVguplB<7{-`{d`PTiaPPGDrrM=9OgTriNt}XC~#OI_Bl&mn4>C=I0eN zGU!hhVbt^qEKMz{1gc~$OUx-vWn{1pcJ*;}4pB(bD+1c(nWEqpfJSQ)u{5?fUhRtA zl@n8-yjmV@p}Z;YKLO5x7B>gV&prG}z~P(Sm9#>_3Fr8DHFsvdd%y4AJ2M~t`~ANG zIFH}&M-F`k`Yr6kfWQeq*s#?dS*yFs4pp%2RFpmE`&*8;QBH;e53D7I6;<~`C-Q?G zfyu?}&Y(5Z+}vJUGB7AGa!YPY+m+siU5)~x55g44IaL!Dh71f_IDip>qJ|CYdc}Gm zYwETiY}r*ANxSOTq~qCTKZv+-jWLwQUt0Wc*wREC*u4-+c@%Kaz=IYZ!Xbh2`(-0w ztUF$H)^!D*9=|_d6G@bf$Z_pOCyZj}k61X2BLagOZf<9x${@xwbgr)5Qk95wVutbF ztM$n7J?WNAd<2ggIA&oKV*-WlB@ELEFV*T1W$GKB_>6%Q0;jSh)t!op@$6+ky6iW+ z>ZPW|#BmfYoW$b-1Lqyji7vz_tJ?3lg$Yb@yrGzf2glO@GExiSazm?JXu4?YXW$8egKgHcK_GXuvL?== zSYV|;Y2jmdis8$OrYT^j+O|Qm%C0xOiq_Vi_r0)DQvp--44ySmve+~q7Z`3k(|&Xn z_`xMv*(8N5ayQTfRhz;mEIfxbXMkePPLC0J+_?V$~9MIQhOOioq$hT_!Jfe`a`*`1Rn3@p}QLO&SeW% zagEY4r7Ggyp3$uuSmDXhmhFlRHFBM}1@6|Nrg0_*%S=|GxX_YQvU%`#LQsy3eDQMD zdwK^jQORWIi6n5Sll4x$$^2}O_4i^hRE}h2i#bl!8(C7(reD1#^_38*fJzQAE6eJ3 z%CmJC_olQr-J^Tx$v#Y((`Twn`wS7t>seLR{l*0|8Ls-AxEIe8UF+MG91E}0In=20 z0#q%gLrLSc#?#3)^uL&Q^bFw!0u?q~_RWEeb4tyrCp#_YlVRr4E_GXUge(6?1osWf zqRpOddpH+is=dMNUnvI-$d+pY=RHlKMtrQS^Q#ge+s_N9+?jg`$un1dqZfkoBbC z!vh2OzKI{;Z392F@FV<~Pquc6INmmk&t8m)bBA1)mE?JrXPdM~|H$@#x+!sRMS4|N zg*=x0twy~^dNT>{*m#|RXP4jqWa4t~z1hP$MV^?XeoOSdm$Io60dbsBz0CIqZvp+l<}ZW4 zt2jfu;^;YA1;2+T{{+$hR~R?@3j51{L4Fqx6j8rKubu=AjCg$#NZ1t;%J}XHZ4N~+i8#= z@~d6W>L7P9Bd~NAXBphN<>{IC@ljwGPv#VlIa``paB!<%5*hLJl1qj>HO& z($yF_9LF&f`PMp#b2t@qnM@qExXhBlZ3boHDcr#h11j(t`X&DAi&-6_C7FArHTPxC zX?}T#f8m^gXZY8o=*JYl(xN!WT{+r@yW-7ebt;Zc`{K%0Y{O}6sd@?YSMe&{>%w`3 zU!CI76nZI#yLf@(l$WLp*9)t=_;ep`OzZsiW%6s2&l$2ji%0Q9CcmRCzoV(&0*3H4 ze4SA>^P5<{K}#m4r2M`~5l`YUeml-}Kfc3J4&TN1_|<*& e2ET8{D+J!6T0g;0@eBNt7L&8T!f)_99R3eO)eUI? literal 2240 zcmb7EU31e$6g_J@Q6ekGiAhSJloUc@JAnE@TUw`Slav6(Ng!rC!|)_qixIK49(f(e zziMaNp=qZd&;3yy?n-M#CI-?MY4`5lbI&<@cmMtG_rCzFVs8>Dqzz;&jA5MNvItr> zf9Z6(ZEp8?aNsq$y&=TD=eKInlwrCN1@?GX^gJnoLxyrSnHj_@gXH7A6$29t`RC4o zW49f@W!Gdt=o2s*Ql4wV!jyrWg)_)AEGpPuSM7KjI34~%1pBt@NXK?X$MJl-CIU%` z4dPHKKB>M5TPcOa-iJ`hVg>~RXD!TPj-hy3H4Mg6&v)0`ZH8OL)72_PEc?=H+f}b8 z!{X;G%;P-6go4{Ryyp^$VnWVt<2i3ik`pQnb9cMa6TZ_XM?YjJ9816bvdP0W10OLg zC$;dwlD#A3mgxI#yxGJ>ELiv$ml?)aJ>QdS4C!L2uDn^aa1~1oXF_^({@mRYqSIrT zDJD6^dWsfGC^KYw&H-mwdb^ge3A8)|*BIuLgge6J?LikQCO0hD_=LfvIF~%KYIYQS z-Na{DF!1?MyG4~4axE_D*mQG~kjy5PB864Y=R5sQg9neCMw=otRnc_XbtmxDTn97q znMX;BLw!H`##9(4YhKHDWIrG{`-EYuLm)$nD{GXksA`^(+#xrs!f%c43kF8@W)oc$ zA2y-p6Y&s(VX7vb=Ki+R)gtrTTs{--14msw$paF+nRNQCrBACU?xMvJrW`kPSVuWA z<+$z+f1%BYuiW6p8n!OF`lHwA-s)G3;lexYr;`0Hy*E5AIj#FHdIO{LD4aB<&Tu_? z4+aF@`6!lXzgZLgpvkv9)pP}2P`|o2lo@n2_WHi`I=t@nJnF@D-xtzRuK=CQ=+~!5 z$Hs*`>~dQ}Rp^SR=w<-a+UnV-kwN2|SfcnBH2a>SjQ(@wU%)bd!g!pXnXLVW>=C9@ z_=#3h_>#Wk;jRL{qOlca;1<57**D>y3dL6OEz%*XPg!Y-pH-+UNBDrCw*SDz$FFed z?=ag$78hub!p?`a(aD-2%@s25S^_&8)6QzY z6CN{at8I Date: Tue, 28 Sep 2021 22:55:18 +0700 Subject: [PATCH 2/2] feat: create spring security for booking service --- .idea/inspectionProfiles/Project_Default.xml | 12 +++ booking/pom.xml | 13 +++- .../java/org/example/BookingApplication.java | 30 ++++++++ .../example/controller/BookingController.java | 2 +- .../example/controller/UserController.java | 51 +++++++++++++ .../filter/CustomAuthenticationFilter.java | 57 ++++++++++++++ .../filter/CustomAuthorizationFilter.java | 71 ++++++++++++++++++ .../org/example/model/RoleToUserForm.java | 9 +++ .../java/org/example/model/UserAccount.java | 24 ++++++ .../main/java/org/example/model/UserRole.java | 21 ++++++ .../example/repository/RoleRepository.java | 8 ++ .../example/repository/UserRepository.java | 8 ++ .../org/example/security/SecurityConfig.java | 58 ++++++++++++++ .../java/org/example/service/UserService.java | 65 ++++++++++++++++ .../org/example/BookingApplication.class | Bin 732 -> 1016 bytes .../controller/BookingController.class | Bin 4158 -> 4174 bytes .../example/controller/UserController.class | Bin 0 -> 4520 bytes .../filter/CustomAuthenticationFilter.class | Bin 0 -> 5592 bytes .../filter/CustomAuthorizationFilter.class | Bin 0 -> 5797 bytes .../org/example/model/RoleToUserForm.class | Bin 0 -> 2231 bytes .../org/example/model/UserAccount.class | Bin 0 -> 4677 bytes .../classes/org/example/model/UserRole.class | Bin 0 -> 2552 bytes .../example/repository/RoleRepository.class | Bin 0 -> 444 bytes .../example/repository/UserRepository.class | Bin 0 -> 458 bytes .../org/example/security/SecurityConfig.class | Bin 0 -> 5908 bytes .../org/example/service/UserService.class | Bin 0 -> 4631 bytes 26 files changed, 424 insertions(+), 5 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 booking/src/main/java/org/example/controller/UserController.java create mode 100644 booking/src/main/java/org/example/filter/CustomAuthenticationFilter.java create mode 100644 booking/src/main/java/org/example/filter/CustomAuthorizationFilter.java create mode 100644 booking/src/main/java/org/example/model/RoleToUserForm.java create mode 100644 booking/src/main/java/org/example/model/UserAccount.java create mode 100644 booking/src/main/java/org/example/model/UserRole.java create mode 100644 booking/src/main/java/org/example/repository/RoleRepository.java create mode 100644 booking/src/main/java/org/example/repository/UserRepository.java create mode 100644 booking/src/main/java/org/example/security/SecurityConfig.java create mode 100644 booking/src/main/java/org/example/service/UserService.java create mode 100644 booking/target/classes/org/example/controller/UserController.class create mode 100644 booking/target/classes/org/example/filter/CustomAuthenticationFilter.class create mode 100644 booking/target/classes/org/example/filter/CustomAuthorizationFilter.class create mode 100644 booking/target/classes/org/example/model/RoleToUserForm.class create mode 100644 booking/target/classes/org/example/model/UserAccount.class create mode 100644 booking/target/classes/org/example/model/UserRole.class create mode 100644 booking/target/classes/org/example/repository/RoleRepository.class create mode 100644 booking/target/classes/org/example/repository/UserRepository.class create mode 100644 booking/target/classes/org/example/security/SecurityConfig.class create mode 100644 booking/target/classes/org/example/service/UserService.class diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..040bf58 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/booking/pom.xml b/booking/pom.xml index 7c7898e..42ee6a2 100644 --- a/booking/pom.xml +++ b/booking/pom.xml @@ -22,10 +22,15 @@ org.springframework.boot spring-boot-starter-data-jpa - - - - + + org.springframework.boot + spring-boot-starter-security + + + com.auth0 + java-jwt + 3.18.1 + org.springframework.boot spring-boot-starter-web diff --git a/booking/src/main/java/org/example/BookingApplication.java b/booking/src/main/java/org/example/BookingApplication.java index 158c901..1116a1e 100644 --- a/booking/src/main/java/org/example/BookingApplication.java +++ b/booking/src/main/java/org/example/BookingApplication.java @@ -1,7 +1,16 @@ package org.example; +import org.example.model.UserRole; +import org.example.model.UserAccount; +import org.example.service.UserService; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.ArrayList; @SpringBootApplication public class BookingApplication @@ -9,4 +18,25 @@ public class BookingApplication public static void main( String[] args ) { SpringApplication.run(BookingApplication.class, args); } + + @Bean + PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +// @Bean +// CommandLineRunner run(UserService userService) { +// return args -> { +// userService.addRole(new UserRole(null, "ROLE_USER")); +// userService.addRole(new UserRole(null, "ROLE_ADMIN")); +// +// userService.addUser(new UserAccount(null, "Minh Quan", "minhquan", "1234", new ArrayList<>())); +// userService.addUser(new UserAccount(null, "Minh Hien", "minhhien", "1234", new ArrayList<>())); +// userService.addUser(new UserAccount(null, "Le Anh", "leanh", "1234", new ArrayList<>())); +// +// userService.addRoleToUser("minhquan", "ROLE_USER"); +// userService.addRoleToUser("leanh", "ROLE_USER"); +// userService.addRoleToUser("leanh", "ROLE_ADMIN"); +// }; +// } } diff --git a/booking/src/main/java/org/example/controller/BookingController.java b/booking/src/main/java/org/example/controller/BookingController.java index 2bab730..14ee535 100644 --- a/booking/src/main/java/org/example/controller/BookingController.java +++ b/booking/src/main/java/org/example/controller/BookingController.java @@ -31,7 +31,7 @@ public ResponseEntity getBookingById(@PathVariable("id") Long id) { return new ResponseEntity<>(bookingService.getBookingById(id), HttpStatus.OK); } - @PostMapping + @PostMapping("/book") public ResponseEntity addNewBooking( @RequestParam("roomId") Long roomId, @RequestParam("customerName") String customerName) { diff --git a/booking/src/main/java/org/example/controller/UserController.java b/booking/src/main/java/org/example/controller/UserController.java new file mode 100644 index 0000000..6c3595f --- /dev/null +++ b/booking/src/main/java/org/example/controller/UserController.java @@ -0,0 +1,51 @@ +package org.example.controller; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.example.model.RoleToUserForm; +import org.example.model.UserRole; +import org.example.model.UserAccount; +import org.example.service.UserService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.net.URI; + +@Slf4j +@RestController +@RequestMapping("api") +@AllArgsConstructor +public class UserController { + private final UserService userService; + + @GetMapping("/users") + public ResponseEntity> getAllUsers() { + return new ResponseEntity<>(userService.getAllUsers(), HttpStatus.OK); + } + + @GetMapping("/user/{username}") + public ResponseEntity getUserByUsername(@PathVariable("username") String username) { + return new ResponseEntity<>(userService.getUserByUsername(username), HttpStatus.OK); + } + + @PostMapping("/user/save") + public ResponseEntity saveUser(@RequestBody UserAccount userAccount) { + URI uri = URI.create(ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/user/save").toUriString()); + return ResponseEntity.created(uri).body(userService.addUser(userAccount)); + } + + @PostMapping("/role/save") + public ResponseEntity saveRole(@RequestBody UserRole userRole) { + URI uri = URI.create(ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/role/save").toUriString()); + return ResponseEntity.created(uri).body(userService.addRole(userRole)); + } + + @PostMapping("/role/addtouser") + public ResponseEntity addRoleToUser(@RequestBody RoleToUserForm roleToUserForm) { + userService.addRoleToUser(roleToUserForm.getUsername(), roleToUserForm.getRoleName()); + return ResponseEntity.ok().build(); + } +} \ No newline at end of file diff --git a/booking/src/main/java/org/example/filter/CustomAuthenticationFilter.java b/booking/src/main/java/org/example/filter/CustomAuthenticationFilter.java new file mode 100644 index 0000000..633c82c --- /dev/null +++ b/booking/src/main/java/org/example/filter/CustomAuthenticationFilter.java @@ -0,0 +1,57 @@ +package org.example.filter; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + private final AuthenticationManager authenticationManager; + + public CustomAuthenticationFilter(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + String username = request.getParameter("username"); + String password = request.getParameter("password"); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + return authenticationManager.authenticate(authenticationToken); + } + + @Override + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { + User user = (User) authResult.getPrincipal(); + Algorithm algorithm = Algorithm.HMAC256("secret".getBytes()); + String access_token = JWT.create() + .withSubject(user.getUsername()) + .withExpiresAt(new Date(System.currentTimeMillis() + 100 * 60 * 1000)) + .withIssuer(request.getRequestURL().toString()) + .withClaim("roles", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList())) + .sign(algorithm); + + Map token = new HashMap<>(); + token.put("access_token", access_token); + response.setContentType("application/json"); + new ObjectMapper().writeValue(response.getOutputStream(), token); + } +} diff --git a/booking/src/main/java/org/example/filter/CustomAuthorizationFilter.java b/booking/src/main/java/org/example/filter/CustomAuthorizationFilter.java new file mode 100644 index 0000000..d3d25d2 --- /dev/null +++ b/booking/src/main/java/org/example/filter/CustomAuthorizationFilter.java @@ -0,0 +1,71 @@ +package org.example.filter; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Arrays.stream; +import static org.springframework.http.HttpHeaders.*; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +@Slf4j +public class CustomAuthorizationFilter extends OncePerRequestFilter { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + if (request.getServletPath().equals("/api/login")) { + filterChain.doFilter(request, response); + } else { + String authorizationHeader = request.getHeader(AUTHORIZATION); + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer")) { + try { + String token = authorizationHeader.substring("Bearer ".length()); + Algorithm algorithm = Algorithm.HMAC256("secret".getBytes()); + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT decodedJWT = verifier.verify(token); + + String username = decodedJWT.getSubject(); + String[] roles = decodedJWT.getClaim("roles").asArray(String.class); + + Collection authorities = new ArrayList<>(); + stream(roles).forEach(role -> { + authorities.add(new SimpleGrantedAuthority(role)); + }); + + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(username, null, authorities); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + + filterChain.doFilter(request, response); + } catch (Exception exception) { + response.setHeader("Error", exception.getMessage()); + response.setStatus(FORBIDDEN.value()); + + Map errors = new HashMap<>(); + errors.put("error_message", exception.getMessage()); + response.setContentType(APPLICATION_JSON_VALUE); + new ObjectMapper().writeValue(response.getOutputStream(), errors); + } + } else { + filterChain.doFilter(request, response); + } + } + } +} diff --git a/booking/src/main/java/org/example/model/RoleToUserForm.java b/booking/src/main/java/org/example/model/RoleToUserForm.java new file mode 100644 index 0000000..f123d43 --- /dev/null +++ b/booking/src/main/java/org/example/model/RoleToUserForm.java @@ -0,0 +1,9 @@ +package org.example.model; + +import lombok.Data; + +@Data +public class RoleToUserForm { + private String username; + private String roleName; +} diff --git a/booking/src/main/java/org/example/model/UserAccount.java b/booking/src/main/java/org/example/model/UserAccount.java new file mode 100644 index 0000000..9f5aeba --- /dev/null +++ b/booking/src/main/java/org/example/model/UserAccount.java @@ -0,0 +1,24 @@ +package org.example.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.Collection; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserAccount { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; + private String username; + private String password; + @ManyToMany(fetch = FetchType.EAGER) + private Collection userRoles = new ArrayList<>(); +} diff --git a/booking/src/main/java/org/example/model/UserRole.java b/booking/src/main/java/org/example/model/UserRole.java new file mode 100644 index 0000000..9dbc279 --- /dev/null +++ b/booking/src/main/java/org/example/model/UserRole.java @@ -0,0 +1,21 @@ +package org.example.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserRole { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; +} diff --git a/booking/src/main/java/org/example/repository/RoleRepository.java b/booking/src/main/java/org/example/repository/RoleRepository.java new file mode 100644 index 0000000..ab7bc66 --- /dev/null +++ b/booking/src/main/java/org/example/repository/RoleRepository.java @@ -0,0 +1,8 @@ +package org.example.repository; + +import org.example.model.UserRole; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RoleRepository extends JpaRepository { + UserRole findByName(String name); +} diff --git a/booking/src/main/java/org/example/repository/UserRepository.java b/booking/src/main/java/org/example/repository/UserRepository.java new file mode 100644 index 0000000..845fedc --- /dev/null +++ b/booking/src/main/java/org/example/repository/UserRepository.java @@ -0,0 +1,8 @@ +package org.example.repository; + +import org.example.model.UserAccount; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + UserAccount findByUsername(String username); +} diff --git a/booking/src/main/java/org/example/security/SecurityConfig.java b/booking/src/main/java/org/example/security/SecurityConfig.java new file mode 100644 index 0000000..47d86a1 --- /dev/null +++ b/booking/src/main/java/org/example/security/SecurityConfig.java @@ -0,0 +1,58 @@ +package org.example.security; + +import lombok.RequiredArgsConstructor; +import org.example.filter.CustomAuthenticationFilter; +import org.example.filter.CustomAuthorizationFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import static org.springframework.http.HttpMethod.*; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig extends WebSecurityConfigurerAdapter { + private final UserDetailsService userDetailsService; + private final BCryptPasswordEncoder bCryptPasswordEncoder; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean()); + customAuthenticationFilter.setFilterProcessesUrl("/api/login"); + http.csrf().disable(); + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + + http.authorizeRequests().antMatchers("/api/login/*").permitAll(); + http.authorizeRequests().antMatchers(GET, "/api/user/*").hasAuthority("ROLE_USER"); + http.authorizeRequests().antMatchers(POST, "/api/user/save/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().antMatchers(POST, "/api/role/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().antMatchers(POST, "/api/v1/booking/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().antMatchers(DELETE, "/api/v1/booking/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().antMatchers(PUT, "/api/v1/booking/checkin/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().antMatchers(PUT, "/api/v1/booking/checkout/*").hasAuthority("ROLE_ADMIN"); + http.authorizeRequests().anyRequest().authenticated(); + + http.addFilter(customAuthenticationFilter); + http.addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); + } + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } +} diff --git a/booking/src/main/java/org/example/service/UserService.java b/booking/src/main/java/org/example/service/UserService.java new file mode 100644 index 0000000..4397bfa --- /dev/null +++ b/booking/src/main/java/org/example/service/UserService.java @@ -0,0 +1,65 @@ +package org.example.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.example.model.UserAccount; +import org.example.model.UserRole; +import org.example.repository.RoleRepository; +import org.example.repository.UserRepository; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional +@Slf4j +public class UserService implements UserDetailsService { + private final UserRepository userRepository; + private final RoleRepository roleRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserAccount userAccount = userRepository.findByUsername(username); + if (userAccount == null) { + throw new UsernameNotFoundException("User not found in the database"); + } + Collection authorities = new ArrayList<>(); + userAccount.getUserRoles().forEach(role -> { + authorities.add(new SimpleGrantedAuthority(role.getName())); + }); + return new org.springframework.security.core.userdetails.User(userAccount.getUsername(), userAccount.getPassword(), authorities); + } + + public List getAllUsers() { + return userRepository.findAll(); + } + + public UserAccount getUserByUsername(String username) { + return userRepository.findByUsername(username); + } + + public UserAccount addUser(UserAccount userAccount) { + userAccount.setPassword(passwordEncoder.encode(userAccount.getPassword())); + return userRepository.save(userAccount); + } + + public UserRole addRole(UserRole userRole) { + return roleRepository.save(userRole); + } + + public void addRoleToUser(String username, String roleName) { + UserAccount userAccount = userRepository.findByUsername(username); + UserRole userRole = roleRepository.findByName(roleName); + userAccount.getUserRoles().add(userRole); + } +} diff --git a/booking/target/classes/org/example/BookingApplication.class b/booking/target/classes/org/example/BookingApplication.class index 229d333b882d9fd53599cfaf688dcaa5e5df986a..4b11ac30302cd79c9f82d25df8b50ba85b98e6e4 100644 GIT binary patch delta 415 zcmZ8cJxc>Y5Pfsul6VLgV@@xA#IME^WYIPj5)s78*7Ceuk!CmCt!OIoC&>PbR9XcT z`~i0M{s*;7CC(-UO&0dOc{6Wjc0b%<$$R^Geg$xZod<7NETKX;Hs4e`$kXIH>*$_H zvR+p!aW!JmI&#v6{m&LUvWny;HxlUXK;HtHkaL=yrXEQRGO@7E_usMdKg2jlBfsr8zh(n_p z7>gN_8Nz|e#hHKtDImdOhA0FRsDdGtA#L(Mp6dE^h71NKpi(`COdyLH%*q0?SQxk% zR2bqJ5*Sz+gc+n6vKitS*cgI=@`5Z3fj}x9h%r~i66}sV zusd{FfC3R9!D66ZxRcTu7^Ps&%R~rg0h#$==V?y1<_jX)i3Q|2v5vI2h{ qcM;sf#gqAX!9aOI z7KT6|l?KEaK%5E0K0wUGkj>x+r1^k`=YXsP+EUDr3wDPt3s4{eBv=g83wKf)1EUno zc^L@dOdvB4>^#lM-h4qsJ29U;Cl(NJq6ju8PB!4L<1U1IxM=cDenrOO$+!7Kv|w*UYD diff --git a/booking/target/classes/org/example/controller/UserController.class b/booking/target/classes/org/example/controller/UserController.class new file mode 100644 index 0000000000000000000000000000000000000000..d4309c14a47faeed2ffc0b9c10fcbaf6099dfc6d GIT binary patch literal 4520 zcmb_g30Krs6#gC{BV!aDt>V%uij~D0t!o9TK;1zpBeYg)o0*9a%p_xyL9N~F-rB|P z`+w+)*q+lL&>z*)?z3+ba-WUG;@2`IV^x@|O8U(i4&ZO!V z9K)Ktr#!Eqj_Gc}wp{&)+y0u+q&JBqmL#AkSc+u=8yB!=fJxmO zFijcP6-ae<4Nq$`np*S>Qyn&3ueSxuu_A$#f|Xb$u%+gHk8{&$PxFfO({Sb#_voXI z<)&gw!~&}otU;SVbDv=uUcbP>&H#p~S(ECS%(R~Mdh7DmH6a;Tr(iuc2&~}d$V9nzwVh>9abJ&DurFBgV(DF@a4A+Ob(+D2{`xdPZfC8B_OE zw^%6Hj;E%B>v6{zvhx&!Zh7ut(J*tm!%bgu?EFyCad=mzT)*axYTlHLMNKvN+M7vZ{!kol>TTl9qyw;__$jh+OyD|iAs1a{Th zLQM}8qi54~fI(nYNsPV>)1DzvfkRP-!V-(uU5rO+>zR_a*tzsjTS**Ma16(TO^@+` zU&<0@sn=DCOFphydH%yBPU2Jo!wN>EqBh;@N1C0rCA&v$Cm(dPQmM<;XB3RerLxOO z+tX|TGB;xi(l{%yl)0(+U^kDF5-KjHI@n|cCKNn}=h^G*%L4mr)NBlQRYH*&eL=x_ zTo724k*z_Xr+!})+C{vSz{|3MY68oBg-5!kKx3!uiCN?l&=p+5q`(?qH|C{1)9SE2 zIZ5)gtYwuE9kEmSuDF8Jzb5djbOHoe5;~%otWq)ylT& zG2I){3I#cWnEn~fEE0dS->vDVszUGEm}68%hl^#`4~AYUveD2J#WJFMQ+94tljj!h zo*^$rbN-+q7iNwzgHd#&1no7p>S`*>aH=@nS2w3}hL+?cNsv=dwgiEb^|jwRdOiL6 z2eVKUJZCK+8rDY9G1xJKJd}ouz~zUAsUG(C*3Y8tMx>dn93TYhcQU45DeA5#2V*G{ zvf0WLP7S`~<5HKIS3mdBc;Ixy{d@}O4<}|VntkN5GbB}qoA3vsz(`zBX<8Xt547E7 z(syMoizjB&^ZW~pK1>vS-Ex<$!7e#IJzLhYKu2{D-n-}Jq-%op*q1fKLw+)C7oDtr z)R2-`DQmRy=CeZ%GJyki3zlzN{wbOS@jZ$NA7rU7(@H09i7I z=R3XzG;#0(4Ok~fAHSvKdmTR$JQ*y-1vJ9+-x8a6&8L4uoa_Drjk9R^4XtEFkFahxK5X^(8(gfi&E?xF|l98YkaN<+P^LVxwIE}18;_CvfO(kE!yYs zXllzWw$7q!4(iDEIqa1b5ZqIDai{?m3X(pa4zyyck8e}ppp35_H}MvOw36nx@eZv+ zq&Le*-z_73PlEDUdf!KykVrqEp}>duC=TRMEXX6VAiD{orv}Jd_&5&atun|@VnBX6 zA7mPzg&;>sgUoANNZScgcX}4j&SCs6&WU>n+(~S^A_;CQ6WE5^_?*~6+HRK-eG!A` z%lU}b;49*gdhX|^M3n5lgBQDd{zT)iyo&00RV04096#w-M>&3i|5I3uub~l=blc8P z`O}hWnnUJyOi8aIQXMPE#5cUxfNy=kDSrEo*Wc4B$n_8Sk=OEE-p}8knp^${4ul+? literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/filter/CustomAuthenticationFilter.class b/booking/target/classes/org/example/filter/CustomAuthenticationFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..d5771a1637733836df8a4d0dda484afc3dd03144 GIT binary patch literal 5592 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:cLHC;eG2YZ@g+HlE~xmeQhVq=J)2eVfIzF1ZS2=2)ADfLS#&)+C$n#IC=3S9 zI3C1T6ns_1*YI`LXkTw@Xx*sRV-F7-&Q?9+*$(@eoEw8BiDty`u(t*A9idD&;wZkU z;#>GOmE%Y)keq&qvsx!-0Q#)Q%o~>$bAyJnT_3c#!qXYu8qgh6{tg%Gyb+VBwc6)& zqDH0}nB@t(Th3B>-4e(JR#ZZwl8sdth@c=G>sUB@`=C_LMJ9X}IwrIydyTZqcVP7H zL3k(UQQoemOl6Z>kx`W<#r&zulwIPqDHPE;j-i~LoU>#hnstVWjAP_p4Ev@)q8zHG zoUIoI>Q5a7SjFYBDV$(s}a~SnktR964KD5G2Paca`G@Qy3-0bI8BkhIhZyrbvs1jYPXD z30OA6M7SzqdZi3(JT}@VRCv;xh|&58dm_6r_!*7a=_`_M4jWWv4=F-5;>GENMIZXGbEIl`v)t61p?PYAA<&r%$ zPN%CabF)s~9O%!D87q8mi1*t?Cu7hXTwgM4{ah{Wp>iFz?QyEr3xSsIyav$_7mA1} zqEQubk>CZilJ;hPFKdC;9&Sc!vxw(xLBY~NhzuNarCyuQn3>Hxzd=5C9f=DR}GR2N_b8U$A@fN{0N42 z9>PdlA{C#2nMxdn4V2*4;0VTcrW!>maR}G9sS|iXN-g0)4JzvGZmVxizDA09T?ucj zMeCh-+c@4;!h0n3ZRGm_sZ;Xy@W_X1v7vsW!NI=H2XvJ9gWi~nrAT2JpQ_H{iRIXYX1;N>@J7D^SEH3z-&MGtUO9j@och<{ zR-DIS_I&bcC$|k8|Jrar()8s8c$n0W@$KiYeEq3MyNIDvG-0dnw43;XxQW-&hw%uV z)Wuu$kMLuks&&3>$v^34dl#$*;dq(^~wEI4tB! zAmQ(n5b*s6`Tmo8OHr443b&wM!BGXOf*Tc_s_+?1D7fJX^gT}9|HX3+NipwOUcp2bbRE^@%wBiWv-MR7*K3BpQYOtdc>v4bo90Io1hfXTT^S=4~ zke4zV$l575X@p$QkjC*(WAf+(zI+$HA=!yY>MTaBkZfv1tspisiRhzRp^CX;zL0Ma NWF<}#CyPZ${SVkc-=6>g literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/model/RoleToUserForm.class b/booking/target/classes/org/example/model/RoleToUserForm.class new file mode 100644 index 0000000000000000000000000000000000000000..3e7afa7819df33bcb0c599966a6d7b531a9d6732 GIT binary patch literal 2231 zcma)7O>^5+6g|(DEZI>KH*M0Igf?x{630nRp+IXV0h%^VN)kFv2s5xjaWt_TSqhTe zq5p*82art`Fau$x3x;mW48Ng2gC(V$C&{+lcz}_uci+|hIQQK9q(A`G(U776sDN#qBI~WHsar48RbWbiKW@^^Ms) zu&r{_-L>rUL)W&p+|PW=TXwysfZn3$m`zJyWUU*0Gw>SDURA~$GB7NI=^kA-Xqlt( zlz|bPrm|)_cfW3#w!r9g!aqV+Eq)=5M-7bOtiZsY70Ap{x--+oghQNA)>|;}hK!xD zWME%Lm@x2WJA$krf|0@n1CzK&7(tEP^F}}; z#}7;=@C9xr0mu1IBI*NDK#6hFbw-=($x zYDbkE`ALp?IE^6|w>byvR#10$ADABd5m+9hOUE`f0>bU>XWS0~)eY*FCom{6O?8_; z6zUU-$e`VGf!Ls{7~BlZ+WxwE5Lc-_c(}TLm#J6TI?wW3Hm5V2h?t$~I_rTOl_QYb zbX#7{T5d@GPRkOy^Lb59B+I?+x`7{f=0Q}qKb*nGIo!sQhC8y)Ogq&b-iGto-M7k7 zf~fV&W-V~NCj#Fln;siRL03#?*S7qrHP_v59aK+FLPFEyxb@_~>SO+8!oGbR5~?`F zl4;wUjlinvxF>M6xBTgLe-^~-WShJNQ4}y%9mn#PY}5BGU&DQYD<|sjSC)n~f%E@v z%JxMZ;3AJ+if1Xsi!YQ=;=6!r791sHc)!YBnXBNc&in%LV`%mk@A5H~nC9JxBjW6LL5V$v0q(@=vZBv(-y8-$PZ7O3$Ew2Q__E`VIQ} z?94Ip;g-Ugjal9*%G~c5C@9Zy>JY|UK{>{`w#9fwrO9|DQ&6Q%<~c?VF<4LwnYNK~ z#9Zk_3!?t5L>M|e)Y5 LX%(Na!G(VSTidV2 literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/model/UserAccount.class b/booking/target/classes/org/example/model/UserAccount.class new file mode 100644 index 0000000000000000000000000000000000000000..1debda0ece2b3b0d99ac7a86aa448eef370c928f GIT binary patch literal 4677 zcmcIoU2_{(8GequtCi%nE!(jZg)}Xx6Ku(@pp=%#j=^>9)LF+l{=nHXN1>4{eaeA>n*a7Mx0a>FGqXlQ(*4XT%v!C5?R;Rzd`6t~&diX%@7 zNmo8o6Ms+I7{hr5i~g?Y<)1j@F(yEupRzG7&|X4?S>ZtRc^id>{#s0f=%;Kvg`$ET z<6|aHHT)mt;w(O6<7s@BTx>hF?Rf@Kp=W$zX^0X3oQ-GkoWjXnXUCln{IV0i+Sns_0{*K|&=o#!SiXK~R+3De|s#`C>!R?m0C!X<@aO}ut9SFJkx z%U&(aFmW#`6 zot~wqvt6dQ;`saPf!ql&-*Ut9HVd^2a8ZWhDVYm%mlsw!wJ81r%bxFEsqfx!tLqNQ zk^&9NPG!TXdh#ACjd0r|dyhY0nsFQ8G@gAx{ylPmW-ThY;Uj4_vB5H1al`Fk^O{p- zS%i!oYl;R@O&zM|IC;dVmxx9wMQ@D)V%fxFaoObJuXcoGTHK5tCWMiVNqMfj(Ib{B zE>&>25ynl3Q4GRux5~u{-(%8KQ(B|Nv{p)EP{>5;=%r5&G&-k3e>B)qM1V#YZ35a9 zO%E|411%S^rf)5D$~!C0Uc7qq+UnBE0@t#{@~pbGdWG9SkDjPG7R@U?)|x_kto5~w z*2jKRVGzYk;f*7)kBUWaC~;tqujv-ccmJPXI7Z+zYeBtQb{9RVw5%j&TslulJ5xB_ zrFs|G%t9&g?DIhoN(b7Ds-ZTJ#Md+U2EJ+GUFqN7QW$IPN1lHx*l~*yZ&6EMbjo2+ zW%v4JI}b51a{8jrUfZUMUCcX`%9mS2%x!mu}0o@B_Bm zheMg|5jQ*lBzPDA4@e0)BthW|d>iE37x|py`|~d5@d6b*0a2BZGmd`pSfigj$xyqX z#JV%*zle4?u{k1bt{`#X(Cx*GFrLt;9oJ=ke{vWs!V<~4r%D_D)4 zl=w^tQ~AOH)bA-J&|=QkUPdEC%$%?q1$B*RldW0DVjb5BlX)F-X&u+4B!WWhGOb;1 zba&Z%T$hqlO_zPzktRk(J5(J&fpA3b`wj zyp@cpf1o#Ke2Bq2u%~jyJv`PxoGY1xoGT@BreKmEV(1R~a%L{s2D(tP2)a;82fRUD5Ayge-lSx(Yy1ojC6n3w6WpMbL5kb#^LkEA3?qM-{VQx7pev{5Q&HijljNj;Qo4l!#Y ztI3k3hnO(2m8FNybPw-pG|hNjJ@_$hGECB8ey9VMU_ic$U9PnUPcj%jB?GezYe30l zAwG>gN=bwy^leI(4%WYrxle_`U@64_L8<$6(R!!)K9k6702&zMuquWn+h8qZr#1## zhrum;mx0(Mb;P7))qRYHq^a86S6(0)vh$smU`t?mUEnprYw`m;19a{eQKyeO(CIh; zimkjxo}{V&n$IMkh5Y;YeEv_EdHH?J9$-*!8~MotSox^~^yYKM0s8YflS8cr*iU1y zbPbGRfKSIm(RN+XhXN^q0a_@O#u4!v|A^LY&>NHb&e)*OP@|;>hJLV XHm?-reO}*YvVzlA_#WP43g`X@(v8Ix literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/model/UserRole.class b/booking/target/classes/org/example/model/UserRole.class new file mode 100644 index 0000000000000000000000000000000000000000..7b556dc387d7f5a68ccbaf340175f9c33e87502f GIT binary patch literal 2552 zcma)7U31e$6g_K8k!_U3`5?rQQa(bPI0>edQm_dvgoK#pt4Rp`c&V^=Vi843Et!FT z(&-Nq_!Yo4e3?ZG zX#<)G9bE#)z2;^~KC-rV99i1->e4CQ^<{I_bEH7Zt_$QB9#{{pl4H4>r3KI3tSAo| z6ItX0G}qcDus?xW3z{}jIigGx-RKd>)GT-Q+m_`B934wQm+wE2wV*Qol>+BY^r2rs z-;_a>ar?){6VNbn4ud#qV93NVjuQd~{Vjzo2lsj0EJz6K8N%;MlgcC1*UhW(D``fFRcoEI054E+dVv+#3@I=aI)7B!kxk$B z1L@XesamfHoayl5wsd9F3S@o5a$1t0j321==Hs{G8EO6Tj>2mlTTryn8jv*|3_nTE|8$XxL;rvhe28qHEoc(mZfTzHv&BUz9<^tFKs1W-j1a znMZDj^0=>t+6r@%@b*_?TwaXj1r6Dx3&m_y6?G=Ggwt$jjOsWSnWIJbT42?-7OkE5 zT>8ptb#azqs?1nZ`Yk75#zG(ZXtX60co83gbBE5=p)5!`x8}8)H92Q1J-gezcV3k? zyR$=5XIUG;V=9=x>3M-l=uRY--`j!;69mq-s ztE~C9Dr0tiT1=i&T2G5{0ki6|z-JuG_oZ*(E>%Bt-cH9ba8Kam+o8;HbY`69WirUC zAjLo4nGhJ`s*kI2jzz8~BqlLM1Mftday0QO@B^#_g=w3q060&}XMJ;y*BFHb{HQ zSm{IxA|2)<4!b%ua0ORM`Y6_@<3(~D#Vu55OEcxy`6ayy4Yyew)12w-x)ZcsrGB5# z|0!gR%s=Qcka~q71B3j}h*ubnrrBLFu22k3eI#QsR7jOFU8$g$zA0n+E>oTS)V5gO zawso9XEdpd{Y4i#$8x@MO`8ry9LZN2lrWQ@cmiYUIYz!w_TjRoUKF(WO-2dJS0kMT zyA*kiX{1>ppW+5%>LhZLvlMfF0W+kQ##w%^Z*iuD;@pAung)&H2th$0#A|}~)-=DS z@Om52#%TLZgfZUiZm(QnOx0*T>X7O{FPH}$Y?>(DQOEVf>;*r=bKI@;TI87K*jxMs zqhaF|C!gU^srQ84b1H)F=AxI!R~H1ghj&3L%t}^eAWwtpC4TVvRFU>B21YvAO1&L= jTh*JYi23jWQgNzW-{CLA`Dgrn&T5VBpLJ~D3l#nXz|-*7 literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/repository/RoleRepository.class b/booking/target/classes/org/example/repository/RoleRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..f468f91cb42932b4b26e24ec12d5803bcc9490fc GIT binary patch literal 444 zcmb7>zfQw25QopDCA9pN`V2_0U>2rS3=9k?K-Gu`IGSs4aBRzQDSb5t9)O2JoP$Ke zg2Z5-Zn*D0|NQa!_6`6OI82}?;Mn?7(ks?Zll0_lqk{EoIkTE(KWzei0Y??Spwwte zdH-0^JS4C!;35JV=anfJ9&1`z|11j(C@Y6u;*G-%P{3%ROmVfo;}HSpC)oy`hX_kg zv#wfg3)1qTAs@|Bwz;M7WQ!@rrGb1Spl@2(Fju9)u=EUGb-3TsX^Z{0@Z>L>&XUZs z`X&2~a=Y|%x>lMs#=qk{i;v~(1Z?pc@OKE#H-R1QhTIK!oJ$XO+j|f8+j{T?l75LW literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/repository/UserRepository.class b/booking/target/classes/org/example/repository/UserRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..128124dc063bfbb854a39758e37e4e9810892f37 GIT binary patch literal 458 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 X|G?iL`HS)U5&Q}76TxXduR{D6bv2*v literal 0 HcmV?d00001 diff --git a/booking/target/classes/org/example/service/UserService.class b/booking/target/classes/org/example/service/UserService.class new file mode 100644 index 0000000000000000000000000000000000000000..e9b81937afa4ff89a977f098536a6aeaed20731a GIT binary patch literal 4631 zcmb7H`Bxj)75<)(Js<`w3%p<_0TOJpMl`Y0+QP&@yrjn1MFf}BX*x)Q7&FW$qY*Lb zk~UqEHf`N~-}ikvtwV`Vm*09$PyeKzo__Dm2#t^cmvh9MdGEgOF7LbdzWLXG-~Jnb zG5o#-F*Iq2>)40=0^P1xNSk+z)uL^tOQyGG<;?VRe8>jR0_|nK&6-8GWcjYQE^ul( zy2smEQQNA5nN~ETMMFYID|CSq544N=mMkYfxh`#Rj8#+M$^Plv#+s3~4X2RK`kv(! zG6OX>th#yAR_Z5mIk)Wi84c|Mm!-y1QEpiB2=%h-tog-N@Q5_1$8r6hCArvRIX(We*^@VXW6>y?3A7=lqXV4+ z`^PND^2Y@ZHL`qO!(o9A#RAq@}fcm&-7 z4@U!7=dyraFnwv{tZSPkfusEcLEMy*Dc82mob)D>A`yCZJc`F?s*#gU3Y-Z|-7Xx( zSSmXTAwA_frShuj@rY00q=r*E`Y|BTS#_$aPe5C8y^BU}S)eDXr5KiAJ*Q(HHw6+w37b*nYc%TA9_32{sia!a@jTwgGGOHM z+v-RqF3%_M0*-2Uzd*7Y^k7xP2LvW}KW$n5jIzJ%s%n_EWCytH8IEt}Co0nk%wkbT zPUeZmw2~er@FG$PETN!bS%-z&0!Nf8d+GG;^t4+jnBFBL7c`3&?h2+D=x8LSY;rxU zl@PX$RXB9tb_>j!APJ&E8j1oJ_I7Z4eSapX_1Q{uOWCfGmqjz$aIQz~tU0lr z6R}Y<36*8Y?YkC}Q+}@iB z+$_BDugErfWj6-HRHg&b~N-Q+@z+3UrM>9-p07~7+YJqQ&u z<20`=>l?Y1Yeq4QRAQ?~)7s=UlWfl4Fl4XyO^;Ku6|nHi1Lj*x)+#uLU-s0cBHGzx zB@T?NT!rd`BlRB)TT7HJ8dFp%ARqhpi0@vv7A6_NWDyWJw-cDE5j!EN#gG;O&OUr(%odFt?JXHeqq*4n!Bm9WN^h?q1cQk(an%kF(DBaJ(58>@?X zqpv=_`$l)Z?9`Z7Wq=BmM2$G@dB4sUpgtXuYS<|RwcCuIn;L7qM?OR_-MEN`RM zsyT0!EGGDb!waM#Z(*ck5VX3ILgt#T&y-4sP~=^&I)XcCpY^%K(n^5zT=m(oDU+OZ zUB5($Vvq-=1N-rv1ip*!Y52a5AK-@qk5(In<*d0YW_nu1i93v?O37|z_Eg{g9VJA# zDNu05aPquq_D#F)O1YS+XGvtHX5$>4i;6$^VxV&Oz0oU3h&*N3cGmLEOcFodp_|S# zT0c$jV(~K_U&NP^_yx;lEv*|6LVwnAOi#5kv!vnI>~VDwZWJsHzvUOj?xMVJ1(8KB z&3XX>F5);Q8zV39Df#)PMqY!|$QvZb7RtQ@4^1fX?XQ%IbDS9bGsMs)v>2`p{}XNZ z(YBB}uz`brzmG!;8#ppE{1%Rlyp0}U6MZq<$KV2|hWQ&E*}#*3AV?fO{~uFod-zS) ziv#?K=t3W#PGFRu0A;QZ1`4r;m-$B3xPx^X)rzO^3O-0zda30@_%KcU2-kJ41v9U5 z=A)cxhWHPP zQVFF(qduWzKFPUHQGI~)G{+d{TdR@U4mGNv4hLde{`{^K~p&ymM)K`B2SU~MVy3*$(9+$CdT+|i|cZQ{N*Wm;UB z))G@ZxU0`JozN^s!1tsYob7sOG!>9lL=WU7%oY~t5hw;I|lFL#RVR-v4Q;dPy|PNlDT^- z68{dB4BX4l&M&L@H{&aGJpk_IDF0egvA@9l6IP@vB0}(^)cjS>#qc$JougFp4UXUB d?_2yy>VKOK{0Kk6&+$toA@D2w2ERks{{T}?2Gall literal 0 HcmV?d00001