Skip to content
Snippets Groups Projects
Verified Commit d187b62e authored by Martin Weise's avatar Martin Weise
Browse files

Finally able to create users

parent c121f298
No related branches found
No related tags found
2 merge requests!163Relase 1.3.0,!155Added readme to authentication service and added eureka service
Showing
with 121 additions and 18 deletions
...@@ -16,11 +16,13 @@ import javax.validation.constraints.NotNull; ...@@ -16,11 +16,13 @@ import javax.validation.constraints.NotNull;
public class TokenDto { public class TokenDto {
@NotBlank @NotBlank
@ToString.Exclude
@JsonProperty("access_token") @JsonProperty("access_token")
@Schema(example = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBbFdvalRsa1dBSVVoYTJLWjFvOEluWEtNbVAzUTg0STZiMFFHYkR6aEpvIn0.eyJleHAiOjE2ODAyNjgyNjgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNjkwNjRlNTQtODNhNS00NGYxLWE3OTItNWFjOWU4OTA5YTlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiI4MjQ2OWMyMS0yYjNjLTRmMDctODg1Yi1hMzViMGQ5YTJhNjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwiYWNyIjoiMSIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjQ0NTgwN2VlLTI4NzYtNDYxZC1hOGYzLTRkMjdiMzBjMjFmYSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZmRhIn0.IOQxqWvlPDV9WuFOeLVG-ayexbK8OqylPABghEMSbMpmNlQhSAjbjaMY31uU-uADZRHB-mC8bmRS5PoWNtanuhz0lORDCeissFsbv0UL9Q42CaxG75vFAAD5WsdIHIr-dtEjEiXYtu-qwdg83griAUeO119TTdgldyPxo4jWzNw0ui6W7r4LqP4fSk31iJfxR5urgs5k6Ctzg-fXCORT31-nKz_YJQwLoPO9j4afX_1mnCXY5qFGMSrmPKzB0CArZfUpa_4nqt4Y768yOC3gigAyCjXtvXKkgCmARPSRjERGDdTb6SGbAwRDiVHVy9wy7XZwOcCFMEra9H7mV0Mx2A") @Schema(example = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBbFdvalRsa1dBSVVoYTJLWjFvOEluWEtNbVAzUTg0STZiMFFHYkR6aEpvIn0.eyJleHAiOjE2ODAyNjgyNjgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNjkwNjRlNTQtODNhNS00NGYxLWE3OTItNWFjOWU4OTA5YTlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiI4MjQ2OWMyMS0yYjNjLTRmMDctODg1Yi1hMzViMGQ5YTJhNjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwiYWNyIjoiMSIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjQ0NTgwN2VlLTI4NzYtNDYxZC1hOGYzLTRkMjdiMzBjMjFmYSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZmRhIn0.IOQxqWvlPDV9WuFOeLVG-ayexbK8OqylPABghEMSbMpmNlQhSAjbjaMY31uU-uADZRHB-mC8bmRS5PoWNtanuhz0lORDCeissFsbv0UL9Q42CaxG75vFAAD5WsdIHIr-dtEjEiXYtu-qwdg83griAUeO119TTdgldyPxo4jWzNw0ui6W7r4LqP4fSk31iJfxR5urgs5k6Ctzg-fXCORT31-nKz_YJQwLoPO9j4afX_1mnCXY5qFGMSrmPKzB0CArZfUpa_4nqt4Y768yOC3gigAyCjXtvXKkgCmARPSRjERGDdTb6SGbAwRDiVHVy9wy7XZwOcCFMEra9H7mV0Mx2A")
private String accessToken; private String accessToken;
@NotBlank @NotBlank
@ToString.Exclude
@JsonProperty("refresh_token") @JsonProperty("refresh_token")
@Schema(example = "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4YTczZGYwZS03NzMwLTRiZDEtOGVhOC1mZTdjZWViNmMxYWMifQ.eyJleHAiOjE2ODAyNzAwMDgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNWYyNDIwNDItNmJmZi00ZTQ2LTg2NTAtNDBhY2E3YjVkZjMyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL21hc3RlciIsInN1YiI6IjgyNDY5YzIxLTJiM2MtNGYwNy04ODViLWEzNWIwZDlhMmE2NiIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIn0.-GltWGkIaKUJ4AqRYnGHblTr0ygZm2CsRQB6zz5ePm4") @Schema(example = "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4YTczZGYwZS03NzMwLTRiZDEtOGVhOC1mZTdjZWViNmMxYWMifQ.eyJleHAiOjE2ODAyNzAwMDgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNWYyNDIwNDItNmJmZi00ZTQ2LTg2NTAtNDBhY2E3YjVkZjMyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL21hc3RlciIsInN1YiI6IjgyNDY5YzIxLTJiM2MtNGYwNy04ODViLWEzNWIwZDlhMmE2NiIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIn0.-GltWGkIaKUJ4AqRYnGHblTr0ygZm2CsRQB6zz5ePm4")
private String refreshToken; private String refreshToken;
......
...@@ -10,6 +10,7 @@ import io.micrometer.core.annotation.Timed; ...@@ -10,6 +10,7 @@ import io.micrometer.core.annotation.Timed;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -57,7 +58,8 @@ public class UserEndpoint { ...@@ -57,7 +58,8 @@ public class UserEndpoint {
log.debug("endpoint create a user, data={}", data); log.debug("endpoint create a user, data={}", data);
final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data)); final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data));
log.trace("create user resulted in dto {}", dto); log.trace("create user resulted in dto {}", dto);
return ResponseEntity.ok(dto); return ResponseEntity.status(HttpStatus.CREATED)
.body(dto);
} }
} }
...@@ -31,7 +31,7 @@ server: ...@@ -31,7 +31,7 @@ server:
port: 9098 port: 9098
ssl: ssl:
enabled: true enabled: true
key-alias: server key-alias: user-service
key-store: "./server.keystore" key-store: "./server.keystore"
key-store-type: jks key-store-type: jks
key-store-password: password key-store-password: password
...@@ -51,7 +51,7 @@ eureka: ...@@ -51,7 +51,7 @@ eureka:
client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/ client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/
fda: fda:
ready.path: ./ready ready.path: ./ready
gateway.endpoint: https://localhost:9095 gateway.endpoint: https://gateway-service:9095
keycloak: keycloak:
username: fda username: fda
password: fda password: fda
......
package at.tuwien.auth;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AdminToken {
private static AdminToken instance = null;
private String token;
public static synchronized AdminToken getInstance() {
if (instance == null) {
instance = new AdminToken();
}
return instance;
}
}
package at.tuwien.config; package at.tuwien.config;
import at.tuwien.mapper.AuthenticationMapper;
import lombok.Getter; import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -20,10 +22,18 @@ public class GatewayConfig { ...@@ -20,10 +22,18 @@ public class GatewayConfig {
@Value("${fda.keycloak.password}") @Value("${fda.keycloak.password}")
private String keycloakPassword; private String keycloakPassword;
private final AuthenticationMapper authenticationMapper;
@Autowired
public GatewayConfig(AuthenticationMapper authenticationMapper) {
this.authenticationMapper = authenticationMapper;
}
@Bean @Bean
public RestTemplate restTemplate() { public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate(); final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint));
restTemplate.getMessageConverters().add(authenticationMapper.mappingJackson2HttpMessageConverter());
return restTemplate; return restTemplate;
} }
} }
...@@ -32,17 +32,19 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway { ...@@ -32,17 +32,19 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway {
@Override @Override
public TokenDto getToken() throws RemoteUnavailableException { public TokenDto getToken() throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders(); final HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString()); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
final MultiValueMap<String, String> payload = new LinkedMultiValueMap<>(); final MultiValueMap<String, String> data = new LinkedMultiValueMap<>();
payload.add("username", gatewayConfig.getKeycloakUsername()); data.set("username", gatewayConfig.getKeycloakUsername());
payload.add("password", gatewayConfig.getKeycloakPassword()); data.set("password", gatewayConfig.getKeycloakPassword());
payload.add("grant_type", "password"); data.set("grant_type", "password");
payload.add("client_id", "admin-cli"); data.set("client_id", "admin-cli");
final String url = "/api/auth/realms/master/protocol/openid-connect/token"; final String url = "/api/auth/realms/master/protocol/openid-connect/token";
log.debug("call authentication service {}", url); log.debug("call authentication service {}", url);
log.trace("headers: {}", headers);
log.trace("data: {}", data);
final ResponseEntity<TokenDto> response; final ResponseEntity<TokenDto> response;
try { try {
response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(payload, headers), TokenDto.class); response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(data, headers), TokenDto.class);
} catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) { } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
log.error("Failed to obtain admin token: {}", e.getMessage()); log.error("Failed to obtain admin token: {}", e.getMessage());
throw new RemoteUnavailableException("Failed to obtain admin token", e); throw new RemoteUnavailableException("Failed to obtain admin token", e);
...@@ -57,9 +59,10 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway { ...@@ -57,9 +59,10 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway {
@Override @Override
public void createUser(String token, CreateUserDto data) throws RemoteUnavailableException { public void createUser(String token, CreateUserDto data) throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders(); final HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON.toString()); headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", MediaType.APPLICATION_JSON.toString()); headers.setBearerAuth(token);
headers.add("Authorization", "Bearer: " + token); log.trace("headers: {}", headers);
log.trace("data: {}", data);
final ResponseEntity<Void> response; final ResponseEntity<Void> response;
try { try {
response = restTemplate.exchange("/api/auth/admin/realms/dbrepo/users", HttpMethod.POST, new HttpEntity<>(data, headers), Void.class); response = restTemplate.exchange("/api/auth/admin/realms/dbrepo/users", HttpMethod.POST, new HttpEntity<>(data, headers), Void.class);
......
package at.tuwien.listener;
import at.tuwien.api.auth.TokenDto;
import at.tuwien.auth.AdminToken;
import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.gateway.GatewayServiceGateway;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Log4j2
@Component
public class AdminTokenScheduler {
private final AdminToken adminToken;
private final GatewayServiceGateway gatewayServiceGateway;
@Autowired
public AdminTokenScheduler(GatewayServiceGateway gatewayServiceGateway) {
this.gatewayServiceGateway = gatewayServiceGateway;
this.adminToken = AdminToken.getInstance();
}
@Scheduled(fixedRate = 1000 * 60 * 3)
public void retrieveAdminToken() throws RemoteUnavailableException {
final TokenDto tokenDto = gatewayServiceGateway.getToken();
log.trace("retrieved new admin token: {}", tokenDto);
adminToken.setToken(tokenDto.getAccessToken());
}
}
package at.tuwien.mapper;
import org.mapstruct.Mapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.Collections;
@Mapper(componentModel = "spring")
public interface AuthenticationMapper {
org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AuthenticationMapper.class);
default MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
final MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED));
return mappingJackson2HttpMessageConverter;
}
}
package at.tuwien.mapper; package at.tuwien.mapper;
import at.tuwien.api.auth.CreateUserDto; import at.tuwien.api.auth.CreateUserDto;
import at.tuwien.api.auth.CredentialDto;
import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.GrantedAuthorityDto; import at.tuwien.api.user.GrantedAuthorityDto;
import at.tuwien.api.user.UserBriefDto; import at.tuwien.api.user.UserBriefDto;
...@@ -11,6 +12,8 @@ import org.mapstruct.Mapper; ...@@ -11,6 +12,8 @@ import org.mapstruct.Mapper;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.List;
@Mapper(componentModel = "spring") @Mapper(componentModel = "spring")
public interface UserMapper { public interface UserMapper {
...@@ -22,7 +25,18 @@ public interface UserMapper { ...@@ -22,7 +25,18 @@ public interface UserMapper {
UserBriefDto userToUserBriefDto(User data); UserBriefDto userToUserBriefDto(User data);
CreateUserDto signupRequestDtoToCreateUserDto(SignupRequestDto data); default CreateUserDto signupRequestDtoToCreateUserDto(SignupRequestDto data) {
return CreateUserDto.builder()
.username(data.getUsername())
.email(data.getEmail())
.enabled(true)
.credentials(List.of(CredentialDto.builder()
.temporary(false)
.type("password")
.value(data.getPassword())
.build()))
.build();
}
default GrantedAuthority grantedAuthorityDtoToGrantedAuthority(GrantedAuthorityDto data) { default GrantedAuthority grantedAuthorityDtoToGrantedAuthority(GrantedAuthorityDto data) {
final GrantedAuthority authority = new SimpleGrantedAuthority(data.getAuthority()); final GrantedAuthority authority = new SimpleGrantedAuthority(data.getAuthority());
......
...@@ -2,7 +2,7 @@ package at.tuwien.service.impl; ...@@ -2,7 +2,7 @@ package at.tuwien.service.impl;
import at.tuwien.api.auth.CreateUserDto; import at.tuwien.api.auth.CreateUserDto;
import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.auth.TokenDto; import at.tuwien.auth.AdminToken;
import at.tuwien.entities.user.User; import at.tuwien.entities.user.User;
import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.exception.UserNotFoundException; import at.tuwien.exception.UserNotFoundException;
...@@ -21,6 +21,7 @@ import java.util.Optional; ...@@ -21,6 +21,7 @@ import java.util.Optional;
@Service @Service
public class UserServiceImpl implements UserService { public class UserServiceImpl implements UserService {
private final AdminToken adminToken;
private final UserMapper userMapper; private final UserMapper userMapper;
private final UserRepository userRepository; private final UserRepository userRepository;
private final GatewayServiceGateway authenticationServiceGateway; private final GatewayServiceGateway authenticationServiceGateway;
...@@ -28,6 +29,7 @@ public class UserServiceImpl implements UserService { ...@@ -28,6 +29,7 @@ public class UserServiceImpl implements UserService {
@Autowired @Autowired
public UserServiceImpl(UserMapper userMapper, UserRepository userRepository, public UserServiceImpl(UserMapper userMapper, UserRepository userRepository,
GatewayServiceGateway authenticationServiceGateway) { GatewayServiceGateway authenticationServiceGateway) {
this.adminToken = AdminToken.getInstance();
this.userMapper = userMapper; this.userMapper = userMapper;
this.userRepository = userRepository; this.userRepository = userRepository;
this.authenticationServiceGateway = authenticationServiceGateway; this.authenticationServiceGateway = authenticationServiceGateway;
...@@ -50,10 +52,8 @@ public class UserServiceImpl implements UserService { ...@@ -50,10 +52,8 @@ public class UserServiceImpl implements UserService {
@Override @Override
public User create(SignupRequestDto data) throws RemoteUnavailableException, UserNotFoundException { public User create(SignupRequestDto data) throws RemoteUnavailableException, UserNotFoundException {
final TokenDto dto = authenticationServiceGateway.getToken();
log.debug("obtained authentication token");
final CreateUserDto userDto = userMapper.signupRequestDtoToCreateUserDto(data); final CreateUserDto userDto = userMapper.signupRequestDtoToCreateUserDto(data);
authenticationServiceGateway.createUser(dto.getAccessToken(), userDto); authenticationServiceGateway.createUser(adminToken.getToken(), userDto);
final Optional<User> optional = userRepository.findByUsername(data.getUsername()); final Optional<User> optional = userRepository.findByUsername(data.getUsername());
if (optional.isEmpty()) { if (optional.isEmpty()) {
/* should never occur */ /* should never occur */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment