Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.provedcode.user.controller;

import com.provedcode.user.model.dto.RegistrationDTO;
import com.provedcode.user.model.dto.SessionInfoDTO;
import com.provedcode.user.model.dto.UserInfoDTO;
import com.provedcode.user.service.AuthenticationService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
Expand All @@ -18,13 +18,13 @@ public class AuthenticationController {
AuthenticationService authenticationService;

@PostMapping("/login")
SessionInfoDTO login(Authentication authentication) {
UserInfoDTO login(Authentication authentication) {
return authenticationService.login(authentication.getName(), authentication.getAuthorities());
}

@PostMapping("/register")
@ResponseStatus(HttpStatus.CREATED)
SessionInfoDTO register(@RequestBody @Valid RegistrationDTO user) {
UserInfoDTO register(@RequestBody @Valid RegistrationDTO user) {
return authenticationService.register(user);
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/provedcode/user/model/dto/UserInfoDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.provedcode.user.model.dto;

import lombok.Builder;

@Builder
public record UserInfoDTO(
String token,
Long id,
String login,
String firstName,
String lastName,
String image

) {
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.provedcode.user.service;

import com.provedcode.user.model.dto.RegistrationDTO;
import com.provedcode.user.model.dto.SessionInfoDTO;
import com.provedcode.user.model.dto.UserInfoDTO;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

public interface AuthenticationService {
SessionInfoDTO login(String name, Collection<? extends GrantedAuthority> authorities);
SessionInfoDTO register(RegistrationDTO user);
UserInfoDTO login(String name, Collection<? extends GrantedAuthority> authorities);
UserInfoDTO register(RegistrationDTO user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.provedcode.talent.repo.TalentRepository;
import com.provedcode.user.model.Role;
import com.provedcode.user.model.dto.RegistrationDTO;
import com.provedcode.user.model.dto.SessionInfoDTO;
import com.provedcode.user.model.dto.UserInfoDTO;
import com.provedcode.user.model.entity.Authority;
import com.provedcode.user.model.entity.UserInfo;
import com.provedcode.user.repo.AuthorityRepository;
Expand All @@ -24,10 +24,12 @@

import java.time.Instant;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import static java.time.temporal.ChronoUnit.MINUTES;
import static org.springframework.http.HttpStatus.NOT_FOUND;

@Service
@AllArgsConstructor
Expand All @@ -40,28 +42,46 @@ public class AuthenticationServiceImpl implements AuthenticationService {
PasswordEncoder passwordEncoder;

@Transactional
public SessionInfoDTO login(String name, Collection<? extends GrantedAuthority> authorities) {
return new SessionInfoDTO("User {%s} log-in".formatted(name), generateJWTToken(name, authorities));
public UserInfoDTO login(String name, Collection<? extends GrantedAuthority> authorities) {
Optional<Long> id = userInfoRepository.findByLogin(name).map(userInfo -> userInfo.getTalentId());
if (id.isEmpty()) {
throw new ResponseStatusException(NOT_FOUND, String.format("talent with id = %d not found", id));
}

Optional<UserInfo> userInfo = userInfoRepository.findByLogin(name);
if (userInfo.isEmpty()) {
throw new ResponseStatusException(NOT_FOUND, String.format("talent with name = %s not found", name));
}
Optional<Talent> talent = talentEntityRepository.findById(userInfo.get().getTalentId());

return UserInfoDTO.builder()
.token(generateJWTToken(name, authorities))
.id(talent.get().getId())
.login(userInfo.get().getLogin())
.firstName(talent.get().getFirstName())
.lastName(talent.get().getLastName())
.image(talent.get().getImage())
.build();
}

@Transactional
public SessionInfoDTO register(RegistrationDTO user) {
public UserInfoDTO register(RegistrationDTO user) {
if (userInfoRepository.existsByLogin(user.login())) {
throw new ResponseStatusException(HttpStatus.CONFLICT,
String.format("user with login = {%s} already exists", user.login()));
String.format("user with login = {%s} already exists", user.login()));
}
Talent talent = Talent.builder()
.firstName(user.firstName())
.lastName(user.lastName())
.specialization(user.specialization())
.build();
.firstName(user.firstName())
.lastName(user.lastName())
.specialization(user.specialization())
.build();
talentEntityRepository.save(talent);

UserInfo userInfo = UserInfo.builder()
.talentId(talent.getId())
.login(user.login())
.password(passwordEncoder.encode(user.password()))
.build();
.talentId(talent.getId())
.login(user.login())
.password(passwordEncoder.encode(user.password()))
.build();
userInfo.setAuthorities(Set.of(authorityRepository.findByAuthority(Role.TALENT).orElseThrow()));

userInfoRepository.save(userInfo);
Expand All @@ -72,22 +92,28 @@ public SessionInfoDTO register(RegistrationDTO user) {

log.info("user with login {%s} was saved, his authorities: %s".formatted(userLogin, userAuthorities));

return new SessionInfoDTO("User: {%s} was registered".formatted(userLogin),
generateJWTToken(userLogin, userAuthorities));
return UserInfoDTO.builder()
.token(generateJWTToken(userLogin, userAuthorities))
.id(talent.getId())
.login(userInfo.getLogin())
.firstName(talent.getFirstName())
.lastName(talent.getLastName())
.image(talent.getImage())
.build();
}

private String generateJWTToken(String name, Collection<? extends GrantedAuthority> authorities) {
log.info("=== POST /login === auth.name = {}", name);
log.info("=== POST /login === auth = {}", authorities);
var now = Instant.now();
var claims = JwtClaimsSet.builder()
.issuer("self")
.issuedAt(now)
.expiresAt(now.plus(60, MINUTES))
.subject(name)
.claim("scope", authorities.stream().map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(" ")))
.build();
.issuer("self")
.issuedAt(now)
.expiresAt(now.plus(60, MINUTES))
.subject(name)
.claim("scope", authorities.stream().map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(" ")))
.build();
return jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
}

Expand Down
Loading