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;
public class TokenDto {
@NotBlank
@ToString.Exclude
@JsonProperty("access_token")
@Schema(example = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBbFdvalRsa1dBSVVoYTJLWjFvOEluWEtNbVAzUTg0STZiMFFHYkR6aEpvIn0.eyJleHAiOjE2ODAyNjgyNjgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNjkwNjRlNTQtODNhNS00NGYxLWE3OTItNWFjOWU4OTA5YTlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiI4MjQ2OWMyMS0yYjNjLTRmMDctODg1Yi1hMzViMGQ5YTJhNjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwiYWNyIjoiMSIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjQ0NTgwN2VlLTI4NzYtNDYxZC1hOGYzLTRkMjdiMzBjMjFmYSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZmRhIn0.IOQxqWvlPDV9WuFOeLVG-ayexbK8OqylPABghEMSbMpmNlQhSAjbjaMY31uU-uADZRHB-mC8bmRS5PoWNtanuhz0lORDCeissFsbv0UL9Q42CaxG75vFAAD5WsdIHIr-dtEjEiXYtu-qwdg83griAUeO119TTdgldyPxo4jWzNw0ui6W7r4LqP4fSk31iJfxR5urgs5k6Ctzg-fXCORT31-nKz_YJQwLoPO9j4afX_1mnCXY5qFGMSrmPKzB0CArZfUpa_4nqt4Y768yOC3gigAyCjXtvXKkgCmARPSRjERGDdTb6SGbAwRDiVHVy9wy7XZwOcCFMEra9H7mV0Mx2A")
private String accessToken;
@NotBlank
@ToString.Exclude
@JsonProperty("refresh_token")
@Schema(example = "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4YTczZGYwZS03NzMwLTRiZDEtOGVhOC1mZTdjZWViNmMxYWMifQ.eyJleHAiOjE2ODAyNzAwMDgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNWYyNDIwNDItNmJmZi00ZTQ2LTg2NTAtNDBhY2E3YjVkZjMyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL21hc3RlciIsInN1YiI6IjgyNDY5YzIxLTJiM2MtNGYwNy04ODViLWEzNWIwZDlhMmE2NiIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIn0.-GltWGkIaKUJ4AqRYnGHblTr0ygZm2CsRQB6zz5ePm4")
private String refreshToken;
......
......@@ -10,6 +10,7 @@ import io.micrometer.core.annotation.Timed;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
......@@ -57,7 +58,8 @@ public class UserEndpoint {
log.debug("endpoint create a user, data={}", data);
final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data));
log.trace("create user resulted in dto {}", dto);
return ResponseEntity.ok(dto);
return ResponseEntity.status(HttpStatus.CREATED)
.body(dto);
}
}
......@@ -31,7 +31,7 @@ server:
port: 9098
ssl:
enabled: true
key-alias: server
key-alias: user-service
key-store: "./server.keystore"
key-store-type: jks
key-store-password: password
......@@ -51,7 +51,7 @@ eureka:
client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/
fda:
ready.path: ./ready
gateway.endpoint: https://localhost:9095
gateway.endpoint: https://gateway-service:9095
keycloak:
username: 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;
import at.tuwien.mapper.AuthenticationMapper;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -20,10 +22,18 @@ public class GatewayConfig {
@Value("${fda.keycloak.password}")
private String keycloakPassword;
private final AuthenticationMapper authenticationMapper;
@Autowired
public GatewayConfig(AuthenticationMapper authenticationMapper) {
this.authenticationMapper = authenticationMapper;
}
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint));
restTemplate.getMessageConverters().add(authenticationMapper.mappingJackson2HttpMessageConverter());
return restTemplate;
}
}
......@@ -32,17 +32,19 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway {
@Override
public TokenDto getToken() throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
final MultiValueMap<String, String> payload = new LinkedMultiValueMap<>();
payload.add("username", gatewayConfig.getKeycloakUsername());
payload.add("password", gatewayConfig.getKeycloakPassword());
payload.add("grant_type", "password");
payload.add("client_id", "admin-cli");
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
final MultiValueMap<String, String> data = new LinkedMultiValueMap<>();
data.set("username", gatewayConfig.getKeycloakUsername());
data.set("password", gatewayConfig.getKeycloakPassword());
data.set("grant_type", "password");
data.set("client_id", "admin-cli");
final String url = "/api/auth/realms/master/protocol/openid-connect/token";
log.debug("call authentication service {}", url);
log.trace("headers: {}", headers);
log.trace("data: {}", data);
final ResponseEntity<TokenDto> response;
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) {
log.error("Failed to obtain admin token: {}", e.getMessage());
throw new RemoteUnavailableException("Failed to obtain admin token", e);
......@@ -57,9 +59,10 @@ public class GatewayServiceGatewayImpl implements GatewayServiceGateway {
@Override
public void createUser(String token, CreateUserDto data) throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add("Authorization", "Bearer: " + token);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(token);
log.trace("headers: {}", headers);
log.trace("data: {}", data);
final ResponseEntity<Void> response;
try {
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;
import at.tuwien.api.auth.CreateUserDto;
import at.tuwien.api.auth.CredentialDto;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.GrantedAuthorityDto;
import at.tuwien.api.user.UserBriefDto;
......@@ -11,6 +12,8 @@ import org.mapstruct.Mapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.List;
@Mapper(componentModel = "spring")
public interface UserMapper {
......@@ -22,7 +25,18 @@ public interface UserMapper {
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) {
final GrantedAuthority authority = new SimpleGrantedAuthority(data.getAuthority());
......
......@@ -2,7 +2,7 @@ package at.tuwien.service.impl;
import at.tuwien.api.auth.CreateUserDto;
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.exception.RemoteUnavailableException;
import at.tuwien.exception.UserNotFoundException;
......@@ -21,6 +21,7 @@ import java.util.Optional;
@Service
public class UserServiceImpl implements UserService {
private final AdminToken adminToken;
private final UserMapper userMapper;
private final UserRepository userRepository;
private final GatewayServiceGateway authenticationServiceGateway;
......@@ -28,6 +29,7 @@ public class UserServiceImpl implements UserService {
@Autowired
public UserServiceImpl(UserMapper userMapper, UserRepository userRepository,
GatewayServiceGateway authenticationServiceGateway) {
this.adminToken = AdminToken.getInstance();
this.userMapper = userMapper;
this.userRepository = userRepository;
this.authenticationServiceGateway = authenticationServiceGateway;
......@@ -50,10 +52,8 @@ public class UserServiceImpl implements UserService {
@Override
public User create(SignupRequestDto data) throws RemoteUnavailableException, UserNotFoundException {
final TokenDto dto = authenticationServiceGateway.getToken();
log.debug("obtained authentication token");
final CreateUserDto userDto = userMapper.signupRequestDtoToCreateUserDto(data);
authenticationServiceGateway.createUser(dto.getAccessToken(), userDto);
authenticationServiceGateway.createUser(adminToken.getToken(), userDto);
final Optional<User> optional = userRepository.findByUsername(data.getUsername());
if (optional.isEmpty()) {
/* should never occur */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment