diff options
Diffstat (limited to 'src/main/java/com')
16 files changed, 126 insertions, 166 deletions
diff --git a/src/main/java/com/blog/web/WebApplication.java b/src/main/java/com/blog/web/WebApplication.java index 0368f26..f5dd2ef 100644 --- a/src/main/java/com/blog/web/WebApplication.java +++ b/src/main/java/com/blog/web/WebApplication.java @@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class WebApplication { - public static void main(String[] args) { - SpringApplication.run(WebApplication.class, args); - } -}
\ No newline at end of file + public static void main(String[] args) { + SpringApplication.run(WebApplication.class, args); + } +} diff --git a/src/main/java/com/blog/web/controllers/ArticleController.java b/src/main/java/com/blog/web/controllers/ArticleController.java index e60be61..b0bbb0b 100644 --- a/src/main/java/com/blog/web/controllers/ArticleController.java +++ b/src/main/java/com/blog/web/controllers/ArticleController.java @@ -3,7 +3,6 @@ package com.blog.web.controllers; import com.blog.web.dto.ArticleDto; import com.blog.web.models.Article; import com.blog.web.models.UserEntity; -import com.blog.web.security.SecurityUtil; import com.blog.web.services.ArticleService; import com.blog.web.services.UserService; import jakarta.validation.Valid; @@ -27,7 +26,7 @@ public class ArticleController { @GetMapping("/articles") public String listArticles(Model model) { List<ArticleDto> articles = articleService.findAllArticles(); - UserEntity user = userService.getLoggedInUser(); + UserEntity user = userService.getLoggedInUser().orElse(new UserEntity()); model.addAttribute("user", user); model.addAttribute("articles", articles); return "index"; @@ -37,67 +36,54 @@ public class ArticleController { public String showArticle(@PathVariable("articleId") long articleId, Model model) { ArticleDto articleDto = articleService.findArticleById(articleId); model.addAttribute("article", articleDto); - UserEntity user = userService.getLoggedInUser(); + UserEntity user = userService.getLoggedInUser().orElse(new UserEntity()); model.addAttribute("user", user); return "articles/show"; } @GetMapping("/articles/new") public String createArticleForm(Model model) { - UserEntity user = userService.getLoggedInUser(); - model.addAttribute("user", user); - final Article article = new Article(); - model.addAttribute("article", article); + model.addAttribute("user", userService.getLoggedInUser().orElse(new UserEntity())); + model.addAttribute("article", new Article()); return "articles/new"; } @PostMapping("/articles/new") - public String saveArticle(@Valid @ModelAttribute("article") ArticleDto articleDto, - BindingResult result, - Model model) - { - // if un-logged in user tries to create an article + public String saveArticle(@Valid @ModelAttribute("article") ArticleDto articleDto, BindingResult result, Model model) { + // if non-authenticated in user tries to create an article // redirect them to login page - UserEntity user = userService.getLoggedInUser(); - if(userService.getLoggedInUser().getId() == null) { + UserEntity user = userService.getLoggedInUser().orElse(new UserEntity()); + if (user.getId() == null) { return "redirect:/userlogin"; - } - else if(result.hasErrors()) { + } else if (result.hasErrors()) { model.addAttribute("article", articleDto); return "articles/new"; - } - else { + } else { articleService.saveArticle(articleDto); return "redirect:/articles"; } } - @GetMapping("/articles/delete/{articleId}") public String deleteArticle(@PathVariable("articleId") Long articleId) { - UserEntity user = userService.getLoggedInUser(); - ArticleDto article = articleService.findArticleById(articleId); - UserEntity owner = article.getCreatedBy(); - if(owner.equals(user)) { - articleService.delete(articleId); - } + articleService.delete(articleId); return "redirect:/articles"; } @GetMapping("/articles/edit/{articleId}") public String editArticleForm(@PathVariable("articleId") long articleId, Model model) { - UserEntity user = userService.getLoggedInUser(); - model.addAttribute("user", user); - ArticleDto articleDto = articleService.findArticleById(articleId); - model.addAttribute("article", articleDto); + UserEntity user = userService.getLoggedInUser().orElse(null); + if (user != null) { + model.addAttribute("user", user); + ArticleDto articleDto = articleService.findArticleById(articleId); + model.addAttribute("article", articleDto); + } return "articles/edit"; } @PostMapping("/articles/edit/{articleId}") - public String updateArticle(@PathVariable("articleId") Long articleId, - @Valid @ModelAttribute("article") ArticleDto article, - BindingResult result) { - if(result.hasErrors()) { + public String updateArticle(@PathVariable("articleId") Long articleId, @Valid @ModelAttribute("article") ArticleDto article, BindingResult result) { + if (result.hasErrors()) { return "articles/edit"; } article.setId(articleId); @@ -107,14 +93,13 @@ public class ArticleController { @GetMapping("/articles/search") public String searchArticle(@RequestParam(value = "search") String search, Model model) { - UserEntity user = userService.getLoggedInUser(); + UserEntity user = userService.getLoggedInUser().orElse(new UserEntity()); model.addAttribute("user", user); List<ArticleDto> articles = articleService.searchArticles(search); model.addAttribute("articles", articles); return "index"; } - @GetMapping("/") public String getArticles() { return "redirect:/articles"; diff --git a/src/main/java/com/blog/web/controllers/AuthController.java b/src/main/java/com/blog/web/controllers/AuthController.java index a654ad1..efb3672 100644 --- a/src/main/java/com/blog/web/controllers/AuthController.java +++ b/src/main/java/com/blog/web/controllers/AuthController.java @@ -2,7 +2,6 @@ package com.blog.web.controllers; import com.blog.web.dto.RegistrationDto; import com.blog.web.models.UserEntity; -import com.blog.web.security.SecurityUtil; import com.blog.web.services.UserService; import jakarta.validation.Valid; import org.apache.commons.lang3.StringUtils; @@ -15,7 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller public class AuthController { - private UserService userService; + private final UserService userService; public AuthController(UserService userService) { this.userService = userService; @@ -23,7 +22,7 @@ public class AuthController { @GetMapping("/userlogin") public String login(Model model) { - UserEntity user = userService.getLoggedInUser(); + final UserEntity user = userService.getLoggedInUser().orElse(new UserEntity()); model.addAttribute("user", user); return "auth/login"; } @@ -36,27 +35,18 @@ public class AuthController { } @PostMapping("/register/save") - public String register(@Valid @ModelAttribute("user")RegistrationDto user, - BindingResult result, - Model model) { - UserEntity existingUserEmail = userService.findByEmail(user.getEmail()); - if( - existingUserEmail != null && - StringUtils.isBlank(existingUserEmail.getEmail()) - ) { + public String register(@Valid @ModelAttribute("user") RegistrationDto user, BindingResult result, Model model) { + UserEntity existingUserEmail = userService.findByEmail(user.getEmail()).orElse(null); + if (existingUserEmail != null && StringUtils.isBlank(existingUserEmail.getEmail())) { result.rejectValue("email", "There is already a user with this email"); } - UserEntity existingUsername = userService.findByUsername(user.getUsername()); - if( - existingUsername != null && - StringUtils.isBlank(existingUsername.getUsername()) - ) - { + UserEntity existingUsername = userService.findByUsername(user.getUsername()).orElse(null); + if (existingUsername != null && StringUtils.isBlank(existingUsername.getUsername())) { result.rejectValue("username", "There is already a user with this username"); } - if(result.hasErrors()) { + if (result.hasErrors()) { model.addAttribute("user", user); return "register"; } diff --git a/src/main/java/com/blog/web/dto/ArticleDto.java b/src/main/java/com/blog/web/dto/ArticleDto.java index 372b318..d275f3b 100644 --- a/src/main/java/com/blog/web/dto/ArticleDto.java +++ b/src/main/java/com/blog/web/dto/ArticleDto.java @@ -29,15 +29,7 @@ public class ArticleDto { @JoinColumn(name = "created_by", nullable = false) private UserEntity createdBy; - public ArticleDto( - long id, - String title, - String photoUrl, - String content, - UserEntity createdBy, - LocalDateTime createdOn, - LocalDateTime updatedOn - ) { + public ArticleDto(long id, String title, String photoUrl, String content, UserEntity createdBy, LocalDateTime createdOn, LocalDateTime updatedOn) { this.id = id; this.title = title; this.photoUrl = photoUrl; @@ -47,7 +39,10 @@ public class ArticleDto { this.updatedOn = updatedOn; } - public ArticleDto() {}; + public ArticleDto() { + } + + ; public ArticleDto(Article article) { this.id = article.getId(); @@ -114,4 +109,6 @@ public class ArticleDto { public void setCreatedBy(UserEntity createdBy) { this.createdBy = createdBy; } + + public String getUsername() { return createdBy.getUsername(); } } diff --git a/src/main/java/com/blog/web/dto/RegistrationDto.java b/src/main/java/com/blog/web/dto/RegistrationDto.java index fcf5f90..5b86557 100644 --- a/src/main/java/com/blog/web/dto/RegistrationDto.java +++ b/src/main/java/com/blog/web/dto/RegistrationDto.java @@ -1,7 +1,5 @@ package com.blog.web.dto; -import com.blog.web.models.UserEntity; -import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotEmpty; public class RegistrationDto { @@ -10,16 +8,14 @@ public class RegistrationDto { private String username; @NotEmpty private String email; + @NotEmpty private String password; - public RegistrationDto() {}; + public RegistrationDto() { + } - public RegistrationDto( - String username, - String email, - String password - ) { + public RegistrationDto(String username, String email, String password) { this.username = username; this.email = email; this.password = password; @@ -49,11 +45,11 @@ public class RegistrationDto { this.email = email; } - public @NotEmpty String getPassword() { - return password; - } - public void setPassword(@NotEmpty String password) { this.password = password; } + + public @NotEmpty String getPassword() { + return password; + } } diff --git a/src/main/java/com/blog/web/mappers/ArticleMapper.java b/src/main/java/com/blog/web/mappers/ArticleMapper.java index 680f67e..4010052 100644 --- a/src/main/java/com/blog/web/mappers/ArticleMapper.java +++ b/src/main/java/com/blog/web/mappers/ArticleMapper.java @@ -4,6 +4,9 @@ import com.blog.web.dto.ArticleDto; import com.blog.web.models.Article; public class ArticleMapper { + private ArticleMapper() { + } + public static Article mapToArticle(ArticleDto articleDto) { return new Article(articleDto); } diff --git a/src/main/java/com/blog/web/models/Article.java b/src/main/java/com/blog/web/models/Article.java index 42d27a1..ed4ac1c 100644 --- a/src/main/java/com/blog/web/models/Article.java +++ b/src/main/java/com/blog/web/models/Article.java @@ -23,15 +23,7 @@ public class Article { @JoinColumn(name = "created_by", nullable = false) private UserEntity createdBy; - public Article( - Long id, - String title, - String photoUrl, - String content, - UserEntity createdBy, - LocalDateTime createdOn, - LocalDateTime updatedOn - ) { + public Article(Long id, String title, String photoUrl, String content, UserEntity createdBy, LocalDateTime createdOn, LocalDateTime updatedOn) { this.id = id; this.title = title; this.photoUrl = photoUrl; @@ -41,7 +33,8 @@ public class Article { this.updatedOn = updatedOn; } - public Article() {}; + public Article() { + } public Article(ArticleDto articleDto) { this.id = articleDto.getId(); diff --git a/src/main/java/com/blog/web/models/UserEntity.java b/src/main/java/com/blog/web/models/UserEntity.java index d121580..c94db6b 100644 --- a/src/main/java/com/blog/web/models/UserEntity.java +++ b/src/main/java/com/blog/web/models/UserEntity.java @@ -18,25 +18,15 @@ public class UserEntity { private String email; private String password; @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @JoinTable( - name = "user_roles", - joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, - inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")} - ) - private List<Role> roles = new ArrayList<>(); + @JoinTable(name = "user_roles", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}) + private final List<Role> roles = new ArrayList<>(); - public boolean equals(UserEntity user) - { + public boolean equals(UserEntity user) { return this.id == user.getId(); } public User toSecurityUser() { - return new User( - this.getEmail(), - this.getPassword(), - this.getRoles().stream().map((role) -> new SimpleGrantedAuthority(role.getName())) - .collect(Collectors.toList()) - ); + return new User(this.getEmail(), this.getPassword(), this.getRoles().stream().map((role) -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList())); } public Long getId() { @@ -76,6 +66,7 @@ public class UserEntity { } public void setRoles(List<Role> roles) { - this.roles = roles; + this.roles.clear(); + this.roles.addAll(roles); } } diff --git a/src/main/java/com/blog/web/repository/RoleRepository.java b/src/main/java/com/blog/web/repository/RoleRepository.java index 08c9ef4..f271bf1 100644 --- a/src/main/java/com/blog/web/repository/RoleRepository.java +++ b/src/main/java/com/blog/web/repository/RoleRepository.java @@ -3,6 +3,8 @@ package com.blog.web.repository; import com.blog.web.models.Role; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface RoleRepository extends JpaRepository<Role, Long> { - Role findByName(String name); + Optional<Role> findByName(String name); } diff --git a/src/main/java/com/blog/web/repository/UserRepository.java b/src/main/java/com/blog/web/repository/UserRepository.java index c304fc0..30eefc5 100644 --- a/src/main/java/com/blog/web/repository/UserRepository.java +++ b/src/main/java/com/blog/web/repository/UserRepository.java @@ -3,9 +3,12 @@ package com.blog.web.repository; import com.blog.web.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface UserRepository extends JpaRepository<UserEntity, Long> { - UserEntity findByEmail(String email); - UserEntity findByUsername(String username); + Optional<UserEntity> findByEmail(String email); + + Optional<UserEntity> findByUsername(String username); - UserEntity findFirstByUsername(String username); + Optional<UserEntity> findFirstByUsername(String username); } diff --git a/src/main/java/com/blog/web/security/CustomUserDetailsService.java b/src/main/java/com/blog/web/security/CustomUserDetailsService.java index f221c9e..ee3e950 100644 --- a/src/main/java/com/blog/web/security/CustomUserDetailsService.java +++ b/src/main/java/com/blog/web/security/CustomUserDetailsService.java @@ -2,8 +2,6 @@ package com.blog.web.security; import com.blog.web.models.UserEntity; import com.blog.web.repository.UserRepository; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -13,7 +11,7 @@ import java.util.stream.Collectors; @Service public class CustomUserDetailsService implements UserDetailsService { - private UserRepository userRepository; + private final UserRepository userRepository; public CustomUserDetailsService(UserRepository userRepository) { this.userRepository = userRepository; @@ -21,12 +19,11 @@ public class CustomUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - UserEntity userEntity = userRepository.findFirstByUsername(username); - if(userEntity != null) { + UserEntity userEntity = userRepository.findFirstByUsername(username).orElse(new UserEntity()); + if (userEntity.getUsername() != null) { return userEntity.toSecurityUser(); - } - else { - throw new UsernameNotFoundException("Invalid username or password"); + } else { + throw new UsernameNotFoundException("Invalid username"); } } } diff --git a/src/main/java/com/blog/web/security/SecurityConfig.java b/src/main/java/com/blog/web/security/SecurityConfig.java index b459224..17e09c7 100644 --- a/src/main/java/com/blog/web/security/SecurityConfig.java +++ b/src/main/java/com/blog/web/security/SecurityConfig.java @@ -28,24 +28,7 @@ public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // disabling csrf leaves us vulnerable, in a real production app do not do this - http.csrf(c -> c.disable()) - .cors(c -> c.disable()) - .authorizeHttpRequests( auths -> auths - .anyRequest() - .permitAll() - ) - .formLogin(form -> form - .loginPage("/userlogin") - .usernameParameter("username") - .passwordParameter("password") - .defaultSuccessUrl("/articles") - .loginProcessingUrl("/userlogin") - .failureUrl("/userlogin?error=true") - .permitAll() - ).logout( - logout -> logout - .logoutUrl("/logout") - .logoutSuccessUrl("/articles")); + http.csrf(c -> c.disable()).cors(c -> c.disable()).authorizeHttpRequests(auths -> auths.anyRequest().permitAll()).formLogin(form -> form.loginPage("/userlogin").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/articles").loginProcessingUrl("/userlogin").failureUrl("/userlogin?error=true").permitAll()).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/articles")); return http.build(); } diff --git a/src/main/java/com/blog/web/services/ArticleService.java b/src/main/java/com/blog/web/services/ArticleService.java index aeedcb4..f0fb05b 100644 --- a/src/main/java/com/blog/web/services/ArticleService.java +++ b/src/main/java/com/blog/web/services/ArticleService.java @@ -2,18 +2,20 @@ package com.blog.web.services; import com.blog.web.dto.ArticleDto; import com.blog.web.models.Article; + import java.util.List; +import java.util.Optional; public interface ArticleService { List<ArticleDto> findAllArticles(); - Article saveArticle(ArticleDto article); + Optional<Article> saveArticle(ArticleDto article); ArticleDto findArticleById(long articleId); void updateArticle(ArticleDto articleDto); - void delete(Long articleId); + boolean delete(Long articleId); List<ArticleDto> searchArticles(String search); } diff --git a/src/main/java/com/blog/web/services/UserService.java b/src/main/java/com/blog/web/services/UserService.java index 270c2ef..b9c231b 100644 --- a/src/main/java/com/blog/web/services/UserService.java +++ b/src/main/java/com/blog/web/services/UserService.java @@ -3,12 +3,14 @@ package com.blog.web.services; import com.blog.web.dto.RegistrationDto; import com.blog.web.models.UserEntity; +import java.util.Optional; + public interface UserService { void saveUser(RegistrationDto registrationDto); - UserEntity findByEmail(String email); + Optional<UserEntity> findByEmail(String email); - UserEntity findByUsername(String username); + Optional<UserEntity> findByUsername(String username); - public UserEntity getLoggedInUser(); + public Optional<UserEntity> getLoggedInUser(); } diff --git a/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java b/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java index acca7e5..fb55c54 100644 --- a/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java +++ b/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java @@ -7,12 +7,15 @@ import com.blog.web.repository.ArticleRepository; import com.blog.web.repository.UserRepository; import com.blog.web.security.SecurityUtil; import com.blog.web.services.ArticleService; +import com.blog.web.services.UserService; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import com.blog.web.mappers.ArticleMapper; + import static com.blog.web.mappers.ArticleMapper.mapToArticle; import static com.blog.web.mappers.ArticleMapper.mapToArticleDto; @@ -20,27 +23,31 @@ import static com.blog.web.mappers.ArticleMapper.mapToArticleDto; public class ArticleServiceImpl implements ArticleService { final private ArticleRepository articleRepository; final private UserRepository userRepository; + final private UserService userService; - public ArticleServiceImpl(ArticleRepository articleRepository, UserRepository userRepository) { + public ArticleServiceImpl(ArticleRepository articleRepository, UserRepository userRepository, UserService userService) { this.userRepository = userRepository; this.articleRepository = articleRepository; + this.userService = userService; } @Override public List<ArticleDto> findAllArticles() { List<Article> articles = articleRepository.findAll(); - //return articles.stream().map((article) -> mapToArticleDto(article)).collect(Collectors.toList()); return articles.stream().map(ArticleMapper::mapToArticleDto).collect(Collectors.toList()); } @Override - public Article saveArticle(ArticleDto articleDto) { + public Optional<Article> saveArticle(ArticleDto articleDto) { String username = SecurityUtil.getSessionUser(); - UserEntity user = userRepository.findByUsername(username); + UserEntity user = userRepository.findByUsername(username).orElse(null); + if (user == null) { + return null; + } Article article = mapToArticle(articleDto); article.setCreatedBy(user); - return articleRepository.save(article); + return Optional.of(articleRepository.save(article)); } @Override @@ -52,15 +59,30 @@ public class ArticleServiceImpl implements ArticleService { @Override public void updateArticle(ArticleDto articleDto) { String username = SecurityUtil.getSessionUser(); - UserEntity user = userRepository.findByUsername(username); + UserEntity user = userRepository.findByUsername(username).orElse(null); + if (user == null) { + return; + } Article article = mapToArticle(articleDto); article.setCreatedBy(user); articleRepository.save(article); } @Override - public void delete(Long articleId) { - articleRepository.deleteById(articleId); + public boolean delete(Long articleId) { + final UserEntity user = userService.getLoggedInUser().orElse(null); + if (user == null) { + return false; + } + String userId = user.getUsername(); + ArticleDto article = this.findArticleById(articleId); + String ownerId = article.getUsername(); + if (ownerId.equals(userId)) { + articleRepository.deleteById(articleId); + return true; + } else { + return false; + } } @Override diff --git a/src/main/java/com/blog/web/services/impl/UserServiceImpl.java b/src/main/java/com/blog/web/services/impl/UserServiceImpl.java index f77eb9e..859e72c 100644 --- a/src/main/java/com/blog/web/services/impl/UserServiceImpl.java +++ b/src/main/java/com/blog/web/services/impl/UserServiceImpl.java @@ -11,17 +11,15 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.Arrays; +import java.util.Optional; @Service public class UserServiceImpl implements UserService { - final private UserRepository userRepository; - final private RoleRepository roleRepository; - final private PasswordEncoder passwordEncoder; + private final UserRepository userRepository; + private final RoleRepository roleRepository; + private final PasswordEncoder passwordEncoder; - public UserServiceImpl( - UserRepository userRepository, - RoleRepository roleRepository, - PasswordEncoder passwordEncoder) { + public UserServiceImpl(UserRepository userRepository, RoleRepository roleRepository, PasswordEncoder passwordEncoder) { this.userRepository = userRepository; this.roleRepository = roleRepository; this.passwordEncoder = passwordEncoder; @@ -32,34 +30,30 @@ public class UserServiceImpl implements UserService { UserEntity user = new UserEntity(); user.setUsername(registrationDto.getUsername()); user.setEmail(registrationDto.getEmail()); - // this is an unsafe way to store passwords in production - // it is left this way only because this is a practice project - //user.setPassword(registrationDto.getPassword()); user.setPassword(passwordEncoder.encode(registrationDto.getPassword())); - final Role role = roleRepository.findByName("User"); + final Role role = roleRepository.findByName("User").orElse(new Role()); user.setRoles(Arrays.asList(role)); userRepository.save(user); } @Override - public UserEntity findByEmail(String email) { + public Optional<UserEntity> findByEmail(String email) { return userRepository.findByEmail(email); } @Override - public UserEntity findByUsername(String username) { + public Optional<UserEntity> findByUsername(String username) { return userRepository.findByUsername(username); } - public UserEntity getLoggedInUser() { - final UserEntity user; + public Optional<UserEntity> getLoggedInUser() { + final Optional<UserEntity> user; String username = SecurityUtil.getSessionUser(); - if(username != null) { + if (username != null) { user = this.findByUsername(username); - } - else { - user = new UserEntity(); + } else { + user = Optional.of(new UserEntity()); } return user; } |
