content: package alexp.blog.service;
  
  import alexp.blog.model.Role;
  import alexp.blog.model.User;
  import alexp.blog.repository.RoleRepository;
  import alexp.blog.repository.UserRepository;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.authentication.AnonymousAuthenticationToken;
  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  import org.springframework.security.core.Authentication;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.context.SecurityContext;
  import org.springframework.security.core.context.SecurityContextHolder;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.security.core.userdetails.UsernameNotFoundException;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.stereotype.Service;
  
  import java.time.LocalDateTime;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  
  @Service("userService")
  public class UserServiceImpl implements UserService {
  
      @Autowired
      private UserRepository userRepository;
  
      @Autowired
      private RoleRepository roleRepository;
  
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      @Override
      public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
          User user = userRepository.findByUsernameOrEmail(s, s);
  
          if (user == null)
              throw new UsernameNotFoundException("no such user");
  
          List<GrantedAuthority> authorities = new ArrayList<>();
          for (Role role : user.getRoles()) {
              authorities.add(new SimpleGrantedAuthority(role.getName()));
          }
  
          return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                  user.isEnabled(), true, true, true, authorities);
      }
  
      @Override
      public User findByEmail(String email) {
          return userRepository.findByEmailIgnoreCase(email);
      }
  
      @Override
      public User findByUsername(String username) {
          return userRepository.findByUsernameIgnoreCase(username);
      }
  
      @Override
      public boolean usernameExists(String username) {
          return findByUsername(username) != null;
      }
  
      @Override
      public boolean emailExists(String email) {
          return findByEmail(email) != null;
      }
  
      @Override
      public void register(User user) {
          user.setPassword(passwordEncoder.encode(user.getPassword()));
  
          user.getRoles().add(roleRepository.findByName("ROLE_USER"));
  
          user.setEnabled(true);
  
          user.setRegistrationDate(LocalDateTime.now());
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void changeEmail(String newEmail, String currentPassword) throws AuthException {
          User user = currentUser();
          if (!passwordEncoder.matches(currentPassword, user.getPassword()))
              throw new AuthException("password does not match");
  
          user.setEmail(newEmail);
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void changePassword(String newPassword, String currentPassword) throws AuthException {
          User user = currentUser();
  
          if (!passwordEncoder.matches(currentPassword, user.getPassword()))
              throw new AuthException("password does not match");
  
          user.setPassword(passwordEncoder.encode(newPassword));
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void changeProfileInfo(User newProfileInfo) {
          User user = currentUser();
  
          user.setAboutText(newProfileInfo.getAboutText());
  
          user.setWebsiteLink(newProfileInfo.getWebsiteLink());
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void changeAvatar(UploadedAvatarInfo uploadedAvatarInfo) {
          User user = currentUser();
  
          user.setBigAvatarLink(uploadedAvatarInfo.bigImageLink);
  
          user.setSmallAvatarLink(uploadedAvatarInfo.smallImageLink);
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void removeAvatar() {
          User user = currentUser();
  
          user.setBigAvatarLink(null);
  
          user.setSmallAvatarLink(null);
  
          userRepository.saveAndFlush(user);
      }
  
      @Override
      public void authenticate(User user) {
          UserDetails userDetails = loadUserByUsername(user.getUsername());
  
          Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
          SecurityContextHolder.getContext().setAuthentication(auth);
      }
  
      @Override
      public boolean isAuthenticated() {
          SecurityContext securityContext = SecurityContextHolder.getContext();
  
          Authentication auth = securityContext.getAuthentication();
  
          return auth != null && !(auth instanceof AnonymousAuthenticationToken) && auth.isAuthenticated();
      }
  
      @Override
      public boolean isAdmin() {
          User user = currentUser();
  
          return user != null && user.hasRole("ROLE_ADMIN");
      }
  
      @Override
      public User currentUser() {
          if (!isAuthenticated())
              return null;
  
          SecurityContext securityContext = SecurityContextHolder.getContext();
  
          Authentication auth = securityContext.getAuthentication();
  
          return userRepository.findByUsernameIgnoreCase(auth.getName());
      }
  
      public PasswordEncoder getPasswordEncoder() {
          return passwordEncoder;
      }
  
      public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
          this.passwordEncoder = passwordEncoder;
      }
  }
  