Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge changes from develop to release #630

Merged
merged 2 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading