Skip to content

Commit

Permalink
Merge pull request #629 from ita-social-projects/bug_fixes
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
VadimasikKPI committed Dec 22, 2023
2 parents a181b06 + e5c33c4 commit 88bd84e
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 80 deletions.
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
postgres:
image: postgres
ports:
- "5432:5432"
- "7000:5432"
environment:
POSTGRES_DB: dokazovi
POSTGRES_USER: dokazovi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.NoArgsConstructor;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
Expand All @@ -16,6 +17,7 @@
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import java.time.LocalDateTime;

@Data
@Builder
Expand All @@ -24,7 +26,7 @@
@Entity(name = "verification_token_entity")
@Table(name = "verification_tokens")
public class VerificationToken {

public static final int EXPIRATION = 1440;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
Expand All @@ -37,4 +39,7 @@ public class VerificationToken {
property = "id",
generator = ObjectIdGenerators.PropertyGenerator.class)
private UserEntity user;

@Column(name = "date_expiration")
private LocalDateTime dateExpiration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@

import com.softserveinc.dokazovi.entity.VerificationToken;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface VerificationTokenRepository extends JpaRepository<VerificationToken, Long> {
Optional<VerificationToken> findByToken(String token);

VerificationToken findByToken(String token);
@Query(nativeQuery = true,
value = "SELECT vt FROM VerificationToken vt WHERE vt.dateExpiration < :currentTime")
List<VerificationToken> findAllExpritedTokens(LocalDateTime currentTime);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.softserveinc.dokazovi.scheduler;

import com.softserveinc.dokazovi.service.VerificationTokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class VerificationTokenCleanupScheduler {
private final VerificationTokenService verificationTokenService;

@Scheduled(cron = "0 0 0 * * ?")
public void deleteExpiredTokens() {
verificationTokenService.deleteExpiredTokens();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.softserveinc.dokazovi.dto.user.UserStatusDTO;
import com.softserveinc.dokazovi.entity.PasswordResetTokenEntity;
import com.softserveinc.dokazovi.entity.UserEntity;
import com.softserveinc.dokazovi.entity.VerificationToken;
import com.softserveinc.dokazovi.pojo.UserSearchCriteria;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -33,10 +32,6 @@ public interface UserService {

void setEnabled(Integer authorId, boolean isEnabled);

void createVerificationToken(UserEntity user, String token);

VerificationToken getVerificationToken(String verificationToken);

UserEntity getById(Integer authorId);

UserEntity getByUserId(Integer userId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.softserveinc.dokazovi.service;

import com.softserveinc.dokazovi.entity.UserEntity;
import com.softserveinc.dokazovi.entity.VerificationToken;

public interface VerificationTokenService {
VerificationToken createVerificationTokenForUser(UserEntity user, String token);

VerificationToken getByToken(String token);

boolean validateVerificationToken(String token);

void delete (VerificationToken passwordResetTokenEntity);

void deleteExpiredTokens();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
import com.softserveinc.dokazovi.pojo.UserSearchCriteria;
import com.softserveinc.dokazovi.repositories.AuthorRepository;
import com.softserveinc.dokazovi.repositories.UserRepository;
import com.softserveinc.dokazovi.repositories.VerificationTokenRepository;
import com.softserveinc.dokazovi.service.MailSenderService;
import com.softserveinc.dokazovi.service.PasswordResetTokenService;
import com.softserveinc.dokazovi.service.ProviderService;
import com.softserveinc.dokazovi.service.UserService;
import com.softserveinc.dokazovi.service.VerificationTokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -45,11 +46,12 @@ public class UserServiceImpl implements UserService {

private final UserRepository userRepository;
private final UserMapper userMapper;
private final VerificationTokenRepository tokenRepository;
private final VerificationTokenService tokenService;
private final PasswordEncoder passwordEncoder;
private final PasswordResetTokenService passwordResetTokenService;
private final MailSenderService mailSenderService;
private final AuthorRepository authorRepository;
private final ProviderService providerService;

private static final String HAS_NO_DIRECTIONS = "hasNoDirections";
private static final String HAS_NO_REGIONS = "hasNoRegions";
Expand Down Expand Up @@ -111,7 +113,7 @@ public UserDTO findExpertByUserId(Integer userId) {
}

/**
* Gets doctors by search criteria. For example, if directions, regions and user name fields are empty, the
* Gets doctors by search criteria. For example, if directions, regions and username fields are empty, the
* findDoctorsProfiles method without parameters is called
*
* @param userSearchCriteria received from User controller
Expand Down Expand Up @@ -207,44 +209,14 @@ public Page<UserDTO> findRandomExpertPreview(Set<Integer> directionsIds, Pageabl
*/
@Override
public void setEnabled(Integer authorId, boolean isEnabled) {
AuthorEntity author = authorRepository.findById(authorId).orElse(null);
if (author == null) {
throw new EntityNotFoundException("Author not found");
}
UserEntity userEntity = userRepository.findById(author.getProfile().getId()).orElse(null);
UserEntity userEntity = getById(authorId);
if (userEntity == null) {
throw new EntityNotFoundException("User not found");
}
userEntity.setEnabled(isEnabled);
userRepository.save(userEntity);
}

/**
* Gets the verification token received from tokenRepository.
*
* @param verificationToken received from Auth controller
* @return found VerificationToken
*/
@Override
public VerificationToken getVerificationToken(String verificationToken) {
return tokenRepository.findByToken(verificationToken);
}

/**
* Gets the verification token received from tokenRepository.
*
* @param user user received from Mail Sender
* @param token token received from Mail Sender
*/
@Override
public void createVerificationToken(UserEntity user, String token) {
VerificationToken myToken = VerificationToken.builder()
.user(user)
.token(token)
.build();
tokenRepository.save(myToken);
}

@Override
public UserEntity getById(Integer authorId) {
AuthorEntity author = authorRepository.findById(authorId).orElse(null);
Expand Down Expand Up @@ -288,43 +260,48 @@ public boolean isPasswordMatches(UserEntity user, String password) {

@Override
public void sendActivationToken(Integer userId, String email, String origin) {
UserEntity user = userRepository.findById(userId).orElse(null);
UserEntity user = getById(userId);
if (user == null) {
throw new EntityNotFoundException("User not found");
}
String token = UUID.randomUUID().toString();
user.setEmail(email);
user.setStatus(UserStatus.NEW);
createVerificationToken(user, token);
user.setEnabled(false);
update(user);
String token = UUID.randomUUID().toString();
tokenService.createVerificationTokenForUser(user, token);
mailSenderService.sendEmailWithActivationToken(origin, token, user);
}

@Override
public void activateUser(UserPasswordDTO userPasswordDTO) {
VerificationToken token = getVerificationToken(userPasswordDTO.getToken());
VerificationToken token = tokenService.getByToken(userPasswordDTO.getToken());
if (!tokenService.validateVerificationToken(userPasswordDTO.getToken())) {
throw new BadRequestException("Token is not valid");
}
UserEntity user = token.getUser();
if (user == null) {
throw new BadRequestException("User not found");
throw new EntityNotFoundException("User not found");
}
user.setEnabled(true);
user.setStatus(UserStatus.ACTIVE);
user.setPassword(passwordEncoder.encode(userPasswordDTO.getNewPassword()));
update(user);
tokenRepository.delete(token);
providerService.createLocalProviderEntityForUser(user, user.getEmail());
tokenService.delete(token);
}

@Override
public UserPublicAndPrivateEmailDTO getAllPublicAndPrivateEmails() {
List<UserEntity> users = userRepository.findAll();
UserPublicAndPrivateEmailDTO userPublicAndPrivateEmailDTO = UserPublicAndPrivateEmailDTO.builder()
return UserPublicAndPrivateEmailDTO.builder()
.publicEmail(Arrays.stream(users.toArray())
.map(user -> ((UserEntity) user).getPublicEmail())
.collect(Collectors.toList()))
.privateEmail(Arrays.stream(users.toArray())
.map(user -> ((UserEntity) user).getEmail())
.collect(Collectors.toList()))
.build();
return userPublicAndPrivateEmailDTO;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.softserveinc.dokazovi.service.impl;

import com.softserveinc.dokazovi.entity.UserEntity;
import com.softserveinc.dokazovi.entity.VerificationToken;
import com.softserveinc.dokazovi.repositories.VerificationTokenRepository;
import com.softserveinc.dokazovi.service.VerificationTokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class VerificationTokenServiceImpl implements VerificationTokenService {

private final VerificationTokenRepository verificationTokenRepository;

@Override
public VerificationToken createVerificationTokenForUser(UserEntity user, String token) {
VerificationToken myToken = VerificationToken.builder()
.token(token)
.user(user)
.dateExpiration(LocalDateTime.now().plusMinutes(VerificationToken.EXPIRATION))
.build();
return verificationTokenRepository.save(myToken);
}

@Override
public VerificationToken getByToken(String token) {
return verificationTokenRepository.findByToken(token).orElse(null);
}

@Override
public boolean validateVerificationToken(String token) {
VerificationToken verificationToken = getByToken(token);
return isAvailable(verificationToken) && !isExpired(verificationToken);
}


@Override
public void delete(VerificationToken verificationToken) {
if (isAvailable(verificationToken)) {
verificationTokenRepository.delete(verificationToken);
}
}

@Override
public void deleteExpiredTokens() {
LocalDateTime currentTime = LocalDateTime.now();
List<VerificationToken> expiredTokens = verificationTokenRepository.findAllExpritedTokens(currentTime);
verificationTokenRepository.deleteAll(expiredTokens);
}

private boolean isAvailable(VerificationToken verificationToken) {
return verificationToken != null;
}

private boolean isExpired(VerificationToken verificationToken) {
return verificationToken.getDateExpiration().isBefore(LocalDateTime.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE verification_tokens
ADD COLUMN date_expiration TIMESTAMP;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.softserveinc.dokazovi.entity.InstitutionEntity;
import com.softserveinc.dokazovi.entity.PasswordResetTokenEntity;
import com.softserveinc.dokazovi.entity.UserEntity;
import com.softserveinc.dokazovi.entity.VerificationToken;
import com.softserveinc.dokazovi.exception.BadRequestException;
import com.softserveinc.dokazovi.exception.EntityNotFoundException;
import com.softserveinc.dokazovi.mapper.UserMapper;
Expand Down Expand Up @@ -388,35 +387,6 @@ void findAll() {
// .findById(any(Integer.class));
// }

@Test
void getVerificationToken() {
String token = "950c9760-805e-449c-a966-2d0d5ebd86f4";
VerificationToken verificationToken = VerificationToken.builder()
.token(token)
.build();
when(tokenRepository.findByToken(any(String.class))).thenReturn(verificationToken);
verificationToken = userService.getVerificationToken(token);
assertEquals(token, verificationToken.getToken());
verify(tokenRepository, times(1))
.findByToken(any(String.class));
}

@Test
void createVerificationToken() {
String token = "950c9760-805e-449c-a966-2d0d5ebd86f4";
UserEntity userEntity = UserEntity.builder().build();
VerificationToken verificationToken = VerificationToken.builder()
.token(token)
.user(userEntity)
.build();
when(tokenRepository.save(any(VerificationToken.class))).thenReturn(verificationToken);
userService.createVerificationToken(userEntity, token);
verify(tokenRepository, times(1))
.save(any(VerificationToken.class));
assertEquals(token, verificationToken.getToken());
assertEquals(userEntity, verificationToken.getUser());
}

@Test
void findUserByEmail() {
String email = "some@some.com";
Expand Down
Loading

0 comments on commit 88bd84e

Please sign in to comment.