From d0d47b48515c83ad4527e8fbd3611bd96d4c3ab6 Mon Sep 17 00:00:00 2001 From: sbalomar Date: Mon, 27 May 2024 11:12:35 +0300 Subject: [PATCH] auth --- starter_code/pom.xml | 30 +++++++-- .../com/example/demo/SareetaApplication.java | 9 ++- .../demo/controllers/UserController.java | 12 +++- .../example/demo/model/persistence/User.java | 14 +++- .../model/requests/CreateUserRequest.java | 21 ++++++ .../security/JWTAuthenticationFilter.java | 61 ++++++++++++++++++ .../JWTAuthenticationVerficationFilter.java | 58 +++++++++++++++++ .../demo/security/SecurityConstants.java | 10 +++ .../demo/security/UserDetailsServiceImpl.java | 28 ++++++++ .../security/WebSecurityConfiguration.java | 46 +++++++++++++ .../com/example/demo/SareetaApplication.class | Bin 995 -> 1393 bytes .../demo/controllers/CartController.class | Bin 4918 -> 4918 bytes .../demo/controllers/ItemController.class | Bin 2756 -> 2756 bytes .../demo/controllers/OrderController.class | Bin 3018 -> 3018 bytes .../demo/controllers/UserController.class | Bin 3643 -> 4320 bytes .../example/demo/model/persistence/Cart.class | Bin 2977 -> 2977 bytes .../example/demo/model/persistence/Item.class | Bin 2322 -> 2322 bytes .../example/demo/model/persistence/User.class | Bin 1771 -> 2232 bytes .../demo/model/persistence/UserOrder.class | Bin 3034 -> 3034 bytes .../repositories/CartRepository.class | Bin 518 -> 604 bytes .../repositories/ItemRepository.class | Bin 560 -> 646 bytes .../repositories/OrderRepository.class | Bin 618 -> 704 bytes .../repositories/UserRepository.class | Bin 503 -> 589 bytes .../model/requests/CreateUserRequest.class | Bin 722 -> 1177 bytes .../model/requests/ModifyCartRequest.class | Bin 1184 -> 1184 bytes .../demo/SareetaApplicationTests.class | Bin 631 -> 631 bytes 26 files changed, 278 insertions(+), 11 deletions(-) create mode 100644 starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java create mode 100644 starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java create mode 100644 starter_code/src/main/java/com/example/demo/security/SecurityConstants.java create mode 100644 starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java create mode 100644 starter_code/src/main/java/com/example/demo/security/WebSecurityConfiguration.java diff --git a/starter_code/pom.xml b/starter_code/pom.xml index 608bb212f..6235f38bc 100644 --- a/starter_code/pom.xml +++ b/starter_code/pom.xml @@ -27,11 +27,17 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-security org.springframework.boot - spring-boot-starter-tomcat + spring-boot-starter-web + + + + com.auth0 + java-jwt + 3.10.3 @@ -44,11 +50,23 @@ spring-boot-starter-test test - - org.codehaus.mojo - tomcat-maven-plugin - 1.1 + org.springframework.security + spring-security-test + test + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.security + spring-security-config + + + org.codehaus.mojo + tomcat-maven-plugin + 1.1 diff --git a/starter_code/src/main/java/com/example/demo/SareetaApplication.java b/starter_code/src/main/java/com/example/demo/SareetaApplication.java index f161f699d..7037ec73f 100644 --- a/starter_code/src/main/java/com/example/demo/SareetaApplication.java +++ b/starter_code/src/main/java/com/example/demo/SareetaApplication.java @@ -3,13 +3,20 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; @EnableJpaRepositories("com.example.demo.model.persistence.repositories") @EntityScan("com.example.demo.model.persistence") -@SpringBootApplication +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) public class SareetaApplication { + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder(){ + return new BCryptPasswordEncoder(); + } public static void main(String[] args) { SpringApplication.run(SareetaApplication.class, args); } diff --git a/starter_code/src/main/java/com/example/demo/controllers/UserController.java b/starter_code/src/main/java/com/example/demo/controllers/UserController.java index 87e8089df..08b617b8b 100644 --- a/starter_code/src/main/java/com/example/demo/controllers/UserController.java +++ b/starter_code/src/main/java/com/example/demo/controllers/UserController.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -27,6 +28,8 @@ public class UserController { @Autowired private CartRepository cartRepository; + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; @GetMapping("/id/{id}") public ResponseEntity findById(@PathVariable Long id) { @@ -38,7 +41,7 @@ public ResponseEntity findByUserName(@PathVariable String username) { User user = userRepository.findByUsername(username); return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user); } - + @PostMapping("/create") public ResponseEntity createUser(@RequestBody CreateUserRequest createUserRequest) { User user = new User(); @@ -46,6 +49,13 @@ public ResponseEntity createUser(@RequestBody CreateUserRequest createUser Cart cart = new Cart(); cartRepository.save(cart); user.setCart(cart); + if(createUserRequest.getPassword().length()<7 || + !createUserRequest.getPassword().equals(createUserRequest.getConfirmPassword())){ + //System.out.println("Error - Either length is less than 7 or pass and conf pass do not match. Unable to create ", + // createUserRequest.getUsername()); + return ResponseEntity.badRequest().build(); + } + user.setPassword(bCryptPasswordEncoder.encode(createUserRequest.getPassword())); userRepository.save(user); return ResponseEntity.ok(user); } diff --git a/starter_code/src/main/java/com/example/demo/model/persistence/User.java b/starter_code/src/main/java/com/example/demo/model/persistence/User.java index ab85ccc60..81a110c35 100644 --- a/starter_code/src/main/java/com/example/demo/model/persistence/User.java +++ b/starter_code/src/main/java/com/example/demo/model/persistence/User.java @@ -26,6 +26,9 @@ public class User { @Column(nullable = false, unique = true) @JsonProperty private String username; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @Column(nullable = false) + private String password; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "cart_id", referencedColumnName = "id") @@ -55,7 +58,12 @@ public String getUsername() { public void setUsername(String username) { this.username = username; } - - - + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } } diff --git a/starter_code/src/main/java/com/example/demo/model/requests/CreateUserRequest.java b/starter_code/src/main/java/com/example/demo/model/requests/CreateUserRequest.java index a92d0bbb6..efdcf64eb 100644 --- a/starter_code/src/main/java/com/example/demo/model/requests/CreateUserRequest.java +++ b/starter_code/src/main/java/com/example/demo/model/requests/CreateUserRequest.java @@ -6,6 +6,12 @@ public class CreateUserRequest { @JsonProperty private String username; + @JsonProperty + private String password; + + @JsonProperty + private String confirmPassword; + public String getUsername() { return username; @@ -14,4 +20,19 @@ public String getUsername() { public void setUsername(String username) { this.username = username; } + + public void setPassword(String password) { + this.password = password; + } + + public void setConfirmPassword(String confirmPassword) { + this.confirmPassword = confirmPassword; + } + public String getPassword() { + return password; + } + + public String getConfirmPassword() { + return confirmPassword; + } } diff --git a/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java b/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java new file mode 100644 index 000000000..dc7ef3f11 --- /dev/null +++ b/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java @@ -0,0 +1,61 @@ +package com.example.demo.security; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +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.web.authentication.UsernamePasswordAuthenticationFilter; + +import com.auth0.jwt.JWT; +import com.example.demo.model.persistence.User; +import com.fasterxml.jackson.databind.ObjectMapper; + +import static com.auth0.jwt.algorithms.Algorithm.HMAC512; + +public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + + private AuthenticationManager authenticationManager; + + public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest req, + HttpServletResponse res) throws AuthenticationException { + try { + User credentials = new ObjectMapper() + .readValue(req.getInputStream(), User.class); + + return authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + credentials.getUsername(), + credentials.getPassword(), + new ArrayList<>())); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + protected void successfulAuthentication(HttpServletRequest req, + HttpServletResponse res, + FilterChain chain, + Authentication auth) throws IOException, ServletException { + + String token = JWT.create() + .withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername()) + .withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME)) + .sign(HMAC512(SecurityConstants.SECRET.getBytes())); + res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token); + } +} diff --git a/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java b/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java new file mode 100644 index 000000000..3d85ab18c --- /dev/null +++ b/starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java @@ -0,0 +1,58 @@ +package com.example.demo.security; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.stereotype.Component; + +import com.auth0.jwt.JWT; + +import static com.auth0.jwt.algorithms.Algorithm.HMAC512; + +@Component +public class JWTAuthenticationVerficationFilter extends BasicAuthenticationFilter { + + public JWTAuthenticationVerficationFilter(AuthenticationManager authManager) { + super(authManager); + } + + @Override + protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) + throws IOException, ServletException { + String header = req.getHeader(SecurityConstants.HEADER_STRING); + + if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) { + chain.doFilter(req, res); + return; + } + + UsernamePasswordAuthenticationToken authentication = getAuthentication(req); + + SecurityContextHolder.getContext().setAuthentication(authentication); + chain.doFilter(req, res); + } + + private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) { + String token = req.getHeader(SecurityConstants.HEADER_STRING); + if (token != null) { + String user = JWT.require(HMAC512(SecurityConstants.SECRET.getBytes())).build() + .verify(token.replace(SecurityConstants.TOKEN_PREFIX, "")) + .getSubject(); + if (user != null) { + return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); + } + return null; + } + return null; + } + +} diff --git a/starter_code/src/main/java/com/example/demo/security/SecurityConstants.java b/starter_code/src/main/java/com/example/demo/security/SecurityConstants.java new file mode 100644 index 000000000..3f7cb5455 --- /dev/null +++ b/starter_code/src/main/java/com/example/demo/security/SecurityConstants.java @@ -0,0 +1,10 @@ +package com.example.demo.security; + +public class SecurityConstants { + + public static final String SECRET = "oursecretkey"; + public static final long EXPIRATION_TIME = 864_000_000; // 10 days + public static final String TOKEN_PREFIX = "Bearer "; + public static final String HEADER_STRING = "Authorization"; + public static final String SIGN_UP_URL = "/api/user/create"; +} diff --git a/starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java b/starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java new file mode 100644 index 000000000..984331456 --- /dev/null +++ b/starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java @@ -0,0 +1,28 @@ +package com.example.demo.security; + +import java.util.Collections; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.example.demo.model.persistence.User; +import com.example.demo.model.persistence.repositories.UserRepository; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = userRepository.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException(username); + } + return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), Collections.emptyList()); + } +} diff --git a/starter_code/src/main/java/com/example/demo/security/WebSecurityConfiguration.java b/starter_code/src/main/java/com/example/demo/security/WebSecurityConfiguration.java new file mode 100644 index 000000000..da0e7f3da --- /dev/null +++ b/starter_code/src/main/java/com/example/demo/security/WebSecurityConfiguration.java @@ -0,0 +1,46 @@ +package com.example.demo.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +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.crypto.bcrypt.BCryptPasswordEncoder; + +@EnableWebSecurity +public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { + + private UserDetailsServiceImpl userDetailsService; + private BCryptPasswordEncoder bCryptPasswordEncoder; + + public WebSecurityConfiguration(UserDetailsServiceImpl userDetailsService, + BCryptPasswordEncoder bCryptPasswordEncoder) { + this.userDetailsService = userDetailsService; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors().and().csrf().disable().authorizeRequests() + .antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll() + .anyRequest().authenticated() + .and() + .addFilter(new JWTAuthenticationFilter(authenticationManager())) + .addFilter(new JWTAuthenticationVerficationFilter(authenticationManager())) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder); + } +} diff --git a/starter_code/target/classes/com/example/demo/SareetaApplication.class b/starter_code/target/classes/com/example/demo/SareetaApplication.class index 388a4f339063ea1af126a63fc5041daef0059d39..47fbede5172d70ffcc031998dc289f15d768f4d9 100644 GIT binary patch delta 619 zcmb7>$x6de6o&tkTGPf_YqievP}_n8McgRP!&0H3hzm*6C@Ce8By~W+jW1C00{RAu z3q`>P@GZnA@BtLhty33nyl~I?&&|pA-{D1mRc4>w?;in7AfrG+Kt@djLDUjr1?@mn zi<-5kuH_1b?h$IIP0RFV2!T|3Lq>=&=U-6sglp&}$MlX>-8tU(Y&BQO>cXNZ*EQEY zw4MC2rQ3PKQ6LMKI)6z@#uU^eDx)ES7#ax~rnUQ*(rG!p)0xQq^*doHmG((WjQ+=T zs{GbNqyDqh9n~z$_B7A5Ep@@r%I7DvB5*fj6s3BCY#iyuQr;kBc{z3V1jiCp~Tek>bv91Qhs{o-dKs)ycd4G2x$tgd`LsjT=OTXep5>pa2OOgis=sh6qXyK!x0J4U__u zf&^+t>IN*rMf_VAWD})L66Bh0;!M&>QXw!Di<$ zKakV>#N6hIsg2&vhD0$TC83?)OS@`m#H`a4l74oRrB~VDGTlGxUz`sg#*cS2F`Dm> zLA+7XYL_aDa@c)Fo(efq^fF8_sTlt(;Iv04G1D62&D%v7L>1G0AvpT?J5^vtx5_?a n?>8jUQCWpVZz$UM@5~lhVNSVDz`VYekWzdX`OL=a-7UQd#|-1XpI(^K&k7X)RB~h(VgIa-RZm-gp z+)6JoTTB~Ny+Q-l>JwsDjSZ(!p$XRuxCdgHNG5hL63yf9GTHMwi57($ag**dn^<{0 zZjsoaun}yM02}qUW_!Dd&A3&fO<@b#1%i2EMl zy(T(vyF{l#1YH7E*~xN!NxF22r=`wDwN+sowhMTOs%O+nX5yK#d}hRh9q5tRsc+h zg%}Q8?dOQ_=~JpPXmk63LL7qvMruf4qn=dD^iQhVAA~@!-Sa_(BvLxyEpVKJ!1+Frq6hr^)KEZIs*7Yz*!xs>GiwtmC1h2D7=LUT4!zRoWkpv5Kxh1GB&a$VWrct zG^uM#MaSAk148U3@bY@Ax%no13g4x@|(3=-(zmqKN4M`*b?Kf>9t zdHb7>@>%37pv_mo@1x8La~7NnYA-;X&6hdKuN?-KW1PSIN!)>Bc#KYg$8nq%vxT2n z3g}DKo`q&tz$GigXUS>Y+!ps4x1(x?y1k=w)IX2 zx7{&=?vS%#4tD{wSh>dl^Y?|Ev#<>84moEqFvT;SII2T|=5Yd~{PQTTA|xI>fhUR7 z2MbT(X>t>$2%f>S#M_A~oWOI;f1a5(i}SIQjJ-gQ55^U&mgu;Ga>=Y0=_?Q{2)x8$ zAe*P%$HbR8#&sV=8n5702Bl5rDJ}$F`;SOkGi0;$Pb3W%{a;8ry?`YC!}2YVDqDwL zB-X)M)lvb8ix|#fWU(AK+hXKn&+p6MAx++(eXq7$72d#`Fj$u_Zb4mJ#D5ijXmR22 zzbj11yv<__ypvZzkgG}B@A9a55xj@@X&2M~0YQF_FFEq7RhZ&(nn63Ml0BSvx$!kF I@ajT;0*Z?^RR910 delta 1737 zcmd5-Nq1C56#nY<>sQI^N>5~xcvj$M)CxR@=Q&;wIDr>A zUJ`g2lL99p1zy3c0-r&`a_-ucCwRuVmoiNTkrI z%L3EL3iM)wz+KoNV}*MXJF>w(y+ND z3vqgGOmh|`D|82ixo6-B=q$`*T>JVOv0-LFp9jsiR&7yzLoPVn?Bh z8x>MLXu+*isT*NBVJr0}h_z_LZB%bB>d{UaI+jzWI$Qy}ov=H|^u zCV5RIe`=M|;YMn#gRE#G1(bhHlZT)|a*fj}iJ0?H|2 PKUF`11N0SU35@&&X!IlT diff --git a/starter_code/target/classes/com/example/demo/controllers/ItemController.class b/starter_code/target/classes/com/example/demo/controllers/ItemController.class index 52ac532e6aed39ad1f16ac7462a25d8f053b5955..bc61cc59c2c28a80b8554d8c5e5dd88833e751f5 100644 GIT binary patch delta 885 zcmZuvOHUJF6g}T`+OM5{t%w%zQ3W5gK((z_K;wLMz$?V%CU1X8rJu8#eT)!Z94TBC^-8aVHc`qTQO2lTP)N z!fBkbUdc>0h)%>L;tE~p76?1qD&;~kIa@HPOcu=XXY1t`j=LP(wwerMT zrLlZzhr+l zx9oW{@jB!AYWO53C8k~{ zmu2tHi*~zNblC-wvEPef`@5L5XN)1rm3b@k;9=>pBYZ`mrnp&}*xW9zlXfbXUC(V< zsqK7$RzOV`i@B|IA!}JVOJKxaFr)T2qmEsM|8yj-Eem+pbP;;EP{joc7)_cyl%y53-soG1S9ASHg>^X0oj3xo!<-_6!B|)`$13m|WcK~b-03hkyP4%GHH*-N zZVKxmfmaX!Zoi{WKfRC+KE10D7LMUK-%CBn2|Bz+M5-d5lGtP{QWYT$%*H=L#Ve>0 zc!uyU{1pTQo*);>>l<_DK8HKR0pc`U-1hl@ E0~W$}LjV8( diff --git a/starter_code/target/classes/com/example/demo/controllers/OrderController.class b/starter_code/target/classes/com/example/demo/controllers/OrderController.class index e8501d29914cfb4992ea75b6a723bee39b1484d1..24b226a4c84036470e0168af44cfaf603e8c4b65 100644 GIT binary patch delta 900 zcmZ{iO;1x%5Qd*~T6){t3zQEjf(nRym6lRPL_k0gq4Fh)Afjl+#z06zD7v(N!RGFC z?OF_q)P-9U{15&Hb*nMXEu;pGxjARf%)B%6zLUEj+z-b0e|`7}bn(DM<1%nt6yZ?> z))G$>(e*^?adhV4T5@Ge;ptyZt!@n{T&->MKD_u0Obb7jB5Xfb;q2I4z)uOK1_6sQ z$`u24OgCmTwf2fuE+iC~gZT5yyTGr>MhFXIY z7AHBS=q>;^j8W-QPlLf}i$=~kU1GY$erNPZqL~(hR*N=54kafM^lq9C*RVx|j_mh& zVc1E`;H10|_GM-F4N^YiypRBHnr9nn&S*(^%7KGxGcpk9>`KWODE9MekHZS*} zAfjTG*rL#T)SGK5A>dW+GXqgXQ){)Dwh zMULZ&?eH#jdo)c;zCDs7s#%EaaeiBBTnyRcW?jaa5IX2`I6?Yxl`)y*r-^amGNqmX z*O-v1Nx^$jKdCk(Iwf9_5;#oD(ahu*P$I?G<;*Uj(%j&tsE2c0)cheX`0_mEh*0dHRMuEcEWfP!gKh;W%>^m7hfzMx>Cpy2jV g1uhnag62*hS}w08@$VMk_gEI+6u(CPwfi35Z@}ApH2?qr delta 885 zcmZ`&+fEZv6kTU#+JWh5t3@q}+~roL6crHx3xXApnD1=vMlzF0Wd!=$Ro3WGbz0CE5a@Mz zby`C0YJKXb_K~@U-1GrsO060Rl`|%@Xyk1CoTSEw;=s;`ytJp?Tgv$BPABFpxSwN0 zj8@QkBHtjsxRfw=Cjl5x&0UrPa2^+k1Zr>*9+$iuXH|oj-I0B0odxI`rtR;Lc^CzF z1orH&@aAF8&|eWPpi;w9G!JW!935dbZq;X<5|L7t;}Xn=TGX+W4=t!i1FJMpS0kFp zYG!-|#4l8v{6boYSg4k!l}kgLJAeSm?OYuz5E-WLq|bDe+B^tE%M#vZ$u&&d;fE+9 zsM1iaV+m>m8Yj%lrja)7G2>KXLMDBIngfVVZQ62Tr1=^EN#*kOd zOg1fzl*~9r(y@KlNvEaj8D~7{_7vv=4LL3h$*kj9zT-{_9O+vipK($$ZDc8KdA_uh z(r{-5ESZNaA;jv@fMpsQbu34dz@h&JCr~?T*{S$cZ%Ux0rEfkLvDW-j&bQLWsjP1~ zwwaDau@b8^tk&@u)(C8M+%dz;x|TgQ>Y5pO#c?N%ao^7xL(94+cp6&-_JlNY9*n?}gaTyvg;yo8rbS09+7$DX z^T^2uJIM*DQcOb!eI1g@DB4jKg@NrFcIeoNE`c43$hz`UPI|s)^tjUWrSim3eo3Hy zO!_77uB7#)5G}Y@9kpA>9_;0IuYCKeO2IIq;hAuD^q8(6#XeN25^zArL9iq=B)MA3 z$4AL%gkh#Wz;hPaL%Jo^Y4Jr_=(+A}XR6SkBaUvzefy~2`W@0gC`I3b{sJ%uLF z(Gn(S)ZSR@h;s9DI!-DdD}N1|p2r%HilQF_8cyjL#Pf3sZQgS%v}tLN`Qt&M?NuG<_IAMRTBD5Dull=@~cOVU?e3RkQseXrE>IIH@B&n~$>& zRGq6^VC_(j-5?`JEYC`$Ww*^bYpTXVckZjmLPDChXN;Oj)j|!kC}4EweCLYg%2bR| z-$Nn=mi1Y-9LQx7(mibwo}tv|B+c}Q=~`-DSgiKPEuPo8Fv=J2<~$@;o>P5J&|50e zT%q|7juctx=i`hqxgKEH9l_EV^Bb1>pnEBhBHz|)jC?BTy|zuo(!421mb-?zw`N`=%DOK$vVTVS?N-Gn zzri42b5_IA;TTc(vIT2ww)57iIp+r-pIJ&790kWEZFeDl4qz_vsa^wX;PR;s;s$u| zIWo49<4g(1d8ksTq3suF?K4;!!9A?F!<7h1D9r)N>io_E3T1E^SBQ3%yO#(~fT=+6 z)xfF-zPiT0*DgSKxQ^HPPE)GB!5;!|;;n)X9&xLhV~wf>jkB6 z@I_wf_bVvT>a+X&@|56hJFv{X7G~0oes*plHZq_#)P7yV+I+8FvtFFv`qQE z7TeK?9dze|dBk{;IuLNwme;n((FAVcBXU&B%UqtLH5kIj z_=I*9*!mlBvZY~P?JQfjifnyaWa~46J|J zxicCKQc2vJxOQz^xbR1)@w+p%CdN$W-gD0V&N<(A?#$Qv)7EGNV>qs@6E;pd2xG{>I8JHnw2dPrz(xJ*&Rh z(=v1;otf&tH!>yAtCmAOZyttz3e(1=H}{>G*(I?a8zfd?wT;UX4Y(q471tz^xGph? z8#bmTZXzu)gIfa4sw>c_>I|#W#;n9`WF)ef^ADP3gIZeTX)x+zznr$s#zt?H!_vw8(~m8!2~;IR71_mMfFzL`y? zz@L8W)px5?H3aq)P|tg-<~p%>&{<3*|IpO{6TgX6l9hy-`RJ<#?J;b)|n86&b(Mq8V) zh2@$U4G20wvzOT7Nr>{Om2cZc2p8>$^UT&3{JQ9(aCMm4dHA}S4>i+3zy zg;p0YqDuQEIYz6=;oZezUU1ZuFp+8bieS8f$pA z7yCGi(v9?#rS+Ai?PrRABL}p!UjIrC5^18JtAPOzTSe;-{ljJaAX4-l`ePj5R51J- Dv7Dh8 diff --git a/starter_code/target/classes/com/example/demo/model/persistence/Cart.class b/starter_code/target/classes/com/example/demo/model/persistence/Cart.class index 5f60d7edd4cf8cd1d6adfc5c733169e068892fd2..9d55dd188cb9dce19ffaae6c96658ff5220bec35 100644 GIT binary patch literal 2977 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 diff --git a/starter_code/target/classes/com/example/demo/model/persistence/Item.class b/starter_code/target/classes/com/example/demo/model/persistence/Item.class index 5bce916c6eeaeafeeb4d27346ef5a6c46d063e44..09670c6b9789f306e017ac6842a2063a6fea41f9 100644 GIT binary patch literal 2322 zcma)-TW=dh6vzMTOY9_@3%QY`3GRiqvE6oCE(MxPnJH5!GH-|nQ{m?aBt$B_i4os(M z3!^R^&v3lDu#Kkh11kuHTN6el6pn_JRcG|-Y51z=?#=gM5JNc(>v#<#8U{Pf8uAS@ zXsj@#+PxxS$8?Nif~GwYuGnS}Xc(OQ-f;O<+c2pcwouq^vYvDM z=lhMPFk&N*-`PeUxU-D?H1LAsc$1qLd}@4VOV6PFtaiP{QJR5Kyv0#s(gAPtl9Vdu z{lrl&{+3iy+J)i5LS}KeFw-dgg4_$_(m$e4z8+)Xi^Z8Ex}+h)jxckXXBtHYEHS~d z+Twf^Cf*{A8N7?z+$4)>yvMf`-siemq+Vf6-qCrD)Y>az#*>u%Ag?&OO0qv=vgK0w z2V^rx-9nDk z{iGdWNhZlUO~wLAuaNUPK44YvU=j1Ui-orQmgD?@W%}G9aDhFXXN)L6{_*6p`d=7h zfjXbucuW06}i)P%YPGKmAS2{ z2osUl32#rV)|jbZF)ibM0@Jx}rbmfPE8Hz=RR`0#Zl)@k*3V#yjz`QitC-gCAc3jS z&9s@w^bn7dmfAFGO_B>(^b literal 2322 zcma)+TXWk)6vzLPEh}- zbU<_vaS$K0{%UxvPCT8DJzW7=zhPqb){$?~4% z3I)R*1+GVd9hZ1EgLct(+O8)ly|&|6tUSlQLV?x_>^dVQwVSRLHO>3>_L8XEuH|sU zKtqJ}z;4MNDJaa^o*m6A$W50viLvN6xOuQw<8=2u60XE;T46Iu!i?2~S5~g@yAX)5?L-Prtw-$Giq%RJ z6~tF<%VDaq>5c|H+1e5HXr}a(^#0aPclXjoCh()C2zYi@MAY;fYgWKcQx`_lwnbFs zu^OH(b%ae1mKG+9Bb_PZHQ6YgTUTSrM!Pm2il%dW;?TvMuFDX846&Aob>?M^<8t*e zPUusZ-d~+}AZxT=&~ST|BU*oc&eGaYbGx1zE>ynRhBamlGLhFBV0f zS(`x&OyV^I12A-~7kh%=g z8t3<`PjMz)B-zP}BtB_zfD3F8$Jd#}k zC`Y;Z8&b(jJ~cEoo1Yt+nrxPThWZ?O?gtd*=K*q`&rR;rB?lRHn3V(5v`P$ECPgJq zaXtx?rpS@+ZM?%I8f(1BFO_>hZ}kOxlGC9nq*h)KGc{B>A!VbhB>N*JTPRn)hnC;3 zJcpLsFCQRZ;q#p|D!)TpNqCJ*Wc?Fk^x%gy4p8`3I^~bpZ^c?&CDS$Nc$fNJ=gbZ2 zag&s{Sl?}uzK6@W!>+!MIn3ZLW;^OzNb3U@Sob9YPqC$!`6Trj&~(lC8>1|65LZ}+ zrqEIL+{9Im-GUMGM=q*yXA{BhWeRqUv`Jg$`Bu57P_Fy}^+@hwJiEl&mg5NHiPs@- zAw8`r(?HC0oy8w#(tDX6Wis7l$1<4oUZxtER!(3_u1Cr=8Z+Id0LPj7dYRTTneI@v z45q$brVTQEbOKXyD^sS4m}w@nPyM}2A7?VnX7{PTm+4b7eRcv<@-s-8&XGyw;gsWi Se5B>S+RrUb?#hIOT* z1THlP(2qmka(l7!Oa)hB<)I9MUp=28W***29Gatt)HXV611dgs({G_ z!?WD}_6o_FGqN8()nzf|t7ppBmDWu}t+*)GM%!P#=X${4Jr(N07Fel{KRj4+!{v0PYYm(q8LcZ2k6wzlOny$XCISsYf?>g-> zu*#3U$T!t}ODA_i$GV}{$*$@hwrgDSvl(>}pM^fUh(QD@b(c+9v$?JcO88b_UEeh$ zH&$BWB|H>Zdm~S_Rni`KpEp#FZCBuvHy7LQZCcaFW0vo$wBJ#Y2!$mqV})L;0oHIM zAdtaTCpgcmp3jeI8GH-Ai_3pP{1HQa!l#}F@jm5K2d4lx`FEi&l+SRB&sUvKQ2L#d zISiZ^Go5eabE>rS7T-EmW6LWqP#P?)|ByiLB39!Fdfyr-SzeEl{eHo(MHVDq0$*aI z&y?dxZ|DT)f8*d~CL@z+6JJr4Fy)y+%{2c4=ZBeYl4<=6rsS|wrpcIT3wQcVr%67+ z#o;{N&Sbia?LN~>dAc~vv_YoLGnkU lQ>H6q%2TQjX(#TKNsjK*e!$GJY`;OBMwvzfO|>isM>7B*cWsa4TPMJ!ZoEE*r7>F1CTgos$! z5#PkxR{ZbG#G`64=iL9yIrsd|nR8eF<{f_dxPJsNffWyQ%vZyW1!WeMNg7x(uq+^R zy8>dZ`2Jjc>MlKq#o|$-v?^b{`aIDW%XIiMRp3fc$`1Ug=nfO8Ga4(+P-p}qFqn8DBqG*sR2LjbpergYW4Yiqt7qzIP zloksvYc~0B3SYd{GmY7_Vxlc*cLhJwl diff --git a/starter_code/target/classes/com/example/demo/model/persistence/UserOrder.class b/starter_code/target/classes/com/example/demo/model/persistence/UserOrder.class index 2c62312c18c279ce0606b4a9ed1fc8086c9b789b..5ac74c397075db90b154c58f75219354a61ac7c8 100644 GIT binary patch literal 3034 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 T8Th~={0ss>nhmH`kbwaJ$Ic~d delta 108 zcmZo;-M}Jz>ff$?3=9k=3BLh2-;s9bM22LP`u(%kw!6G~W+9wOV diff --git a/starter_code/target/classes/com/example/demo/model/persistence/repositories/OrderRepository.class b/starter_code/target/classes/com/example/demo/model/persistence/repositories/OrderRepository.class index e47ebf196d9c7c428bb7de9fee9cf5f4ae021d7e..be357fa65b6bae9735415658281258df42b28da9 100644 GIT binary patch delta 208 zcmaFGa)4Ff)W2Q(7#J8#7=+jvm>3!CC)+bBPd>pYBgxLd!pIH5V5 zMVWc&X+?>-spa`a+4{vLsYR*zC6xuK`a!7$`Nf$f`9+o1Y>W(y49q~x3Umk~&{lQ^ s4hAL$P9Tq!k%0?HaRV_E0}oIUgvHCi$G{)}6ygVx3=C{Qy@Cu302UH1cmMzZ delta 114 zcmX@W`ie#P)W2Q(7#J8#7zEfEc-a~F*ctdYE||zTk>5d>kwG9Uu`E$PCowNw-#;lU zHMwMBhJ`g7BLgD?6A&{4^)a$AGO#eP0{Lt}9xEdQJCNc4VkQPoAcnBG7`VYAJOE_V B5J~_5 diff --git a/starter_code/target/classes/com/example/demo/model/persistence/repositories/UserRepository.class b/starter_code/target/classes/com/example/demo/model/persistence/repositories/UserRepository.class index 54313b79f2b962af4ad68ef299a4d91fd5eb53cf..776f23d03924a06f38b2a5236fb83eaf092bd888 100644 GIT binary patch delta 199 zcmey)e3nJv)W2Q(7#J8#7zEiFm>3!CCfX=Zj$@RTWM^PuWDv+oEKAhSNz6;v_fN`7 zO)g<)V4K{-Xt7aPov~grs5Gx6GdDFXvp6#;C)F`8FTW(QBr`v+n2|x-C%-6Nzqp_% zGcP@@C^0v+JijPgzqll|C^f&NvLIDID77HJII|?bsM4B^k%5tc8Hibd?qCGk%Fe(6 lYx15FO{cX-d-222yBgp_P&%VIjB`RYH+Cpa4+|xjP#-b=X~}UI)s*0ttk~ zfgiw+LOf?9Qa0NImzkaM%zNWE-e13e{3N2MbWo-YWs8)nP@W2mYGd(1a9@NY{$?crb12V^0TMUW#DiOFoo==7AncpBs5Gm645j$4Fu2 zyGWXoIK`+mMHGraGOBkMbf?y+aCGDdZd9o1&`T2$MIW^py5xF=>MmLJbaqCUQl@c!aQ<=;H7UK7aU~*q0eh1J)fQNw;7f zfcw5pO?XCIbO-j|=C4%zjKd5qn%7gC@6tA^T=Ox!yG`Nn;WsKSsNJtZsK^7$(Kq6% zIlUV#zWWZ&^3WfS(Y5} zp&2$=lJWFpEhZH%9tKVZAi>JOHqp(@S|BU2EKxrvF)v-;KPf9Uxr9LxXbua|Tt)^a zkRl+>4&;Go4j|18q=EW@B=_V6Ok(vsP&o#mT3#TV2Pgw#^D*!PX+{PC20@ToAX^_u zgXOfgFfeTZ3NQf`LkwmBD!`^$h(Q>r3Z&T%NHc*{YiVy~VA=@RZNmi?<_Fp+05(Dl Zq6}(3$ash!M1WdY8G#&-qeQ{_#Q;p19g_e6 diff --git a/starter_code/target/classes/com/example/demo/model/requests/ModifyCartRequest.class b/starter_code/target/classes/com/example/demo/model/requests/ModifyCartRequest.class index f5e3fa9a3e65867a6720f56db77f168cdb4e9802..0eb553900e7dbeb6e46a308cce218e03d663e97d 100644 GIT binary patch literal 1184 zcmb7DTTc@~7(LS~mm-v#R^+CFEhKJ?zF|lViAft!1nm2?9m>@1F6>SX{3lH`DKYWE zAK;HNp6T|2Ej;-0eLLS}&iT$a`}@z&UjSZVdjc`U(@12HL`q<$AwNr}DZRS$zS2-t zBanKnJ#BUc;`u^(9Ag+yV0!ras8TVI)S=qsnCSZfnU?7 zS9>xrM^Q*%tQD%jldck&-5Vwx;qx_F`8*Zmz@#uj)k-`I7Ck6h8FTWEu6e zh=W)nU$li2$9^lQs<+xou{g5T=XQ@+=aOQ4R&iQB4+t#ql%ijxkJ+V;#JJI+Sej?P zMcVu9a_9wpa_a}g_s%sBXl?%)(@zh;5?y6FTqu-WI-6SEK@4-C0w46_y$kNkKDwoZ397Vl)#O1lyIc7d2g)CsopnGk! zHde#p8MGQl470B46vF$797uy8YT`6zm^GD{J@rDr&EE(mMR9JMr|Jpwv_h+SO4CxF za+J^0GTqYXnR=}Mk_PKc|A=?39&bx3T2Fx4C7~FY4~8o zxrQnWR)bAee~|V)YO{`0HARqa<5W%6eS-?H*qrX*{I_^O`Zs*kX|ubaXa~7BH|FbtuMJqwxwY-u)hGlNubwv`P0TOge6Ap#den;&Pp-w2*0w zwviPxC7`Zi+8I(}mT3!2+cz-9+K-rW5z`Jmm@th+9+2^6hN--esZ0+iOk8JZ8CZB2SQ*$D83eKt%M$f-67$ma{gbj%lS>#G z*laTMGE3|j8JIOR!`K-(CigJvZd6NT6k||iU|@)#NTfU-;soItiVm=6@&2xKq;mBTdhA!%fUYUGE?3V_uLf=M9; UkSIS;uQ1SHkz@u@1~H(c07umpmH+?% delta 234 zcmYj}I}UMC!b#|-*DSxEv|s?1wMBk?PGe?{>v Zx@5Z9fnq(SKF0x{-GD#C3?qys@ByGo7X1JK