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

Added User modify

parent 277bd57d
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 130 additions and 140 deletions
......@@ -4,7 +4,7 @@ TAG ?= latest
all:
build-backend: build-metadata-db build-database-service build-query-service build-table-service build-identifier-service build-container-service build-discovery-service build-gateway-service build-metadata-service build-analyse-service
build-backend: build-metadata-db build-database-service build-query-service build-table-service build-identifier-service build-container-service build-discovery-service build-gateway-service build-metadata-service build-analyse-service build-user-service
build-metadata-db:
mvn -f ./fda-metadata-db/pom.xml clean install
......@@ -33,6 +33,9 @@ build-query-service: build-metadata-db
build-metadata-service: build-metadata-db
mvn -f ./fda-metadata-service/pom.xml clean package -DskipTests
build-user-service: build-metadata-db
mvn -f ./fda-user-service/pom.xml clean package -DskipTests
build-semantics-service:
bash ./fda-semantics-service/build.sh
......@@ -85,6 +88,9 @@ tag-gateway:
tag-query:
docker tag fda-query-service:latest "dbrepo/query-service:${TAG}"
tag-user:
docker tag fda-user-service:latest "dbrepo/user-service:${TAG}"
tag-table:
docker tag fda-table-service:latest "dbrepo/table-service:${TAG}"
......@@ -129,6 +135,9 @@ release-gateway:
release-query:
docker push "dbrepo/query-service:${TAG}"
release-user:
docker push "dbrepo/user-service:${TAG}"
release-table:
docker push "dbrepo/table-service:${TAG}"
......@@ -144,7 +153,7 @@ release-search:
release-metadata:
docker push "dbrepo/metadata-service:${TAG}"
test-backend: test-container-service test-database-service test-discovery-service test-gateway-service test-query-service test-table-service test-identifier-service test-metadata-service test-semantics-service test-analyse-service
test-backend: test-container-service test-database-service test-discovery-service test-gateway-service test-query-service test-table-service test-identifier-service test-metadata-service test-semantics-service test-analyse-service test-user-service
test-identifier-service: clean build-metadata-db build-identifier-service
mvn -f ./fda-identifier-service/pom.xml clean test verify
......@@ -171,6 +180,9 @@ test-table-service: clean build-metadata-db build-table-service
test-metadata-service: clean build-metadata-db build-metadata-service
mvn -f ./fda-metadata-service/pom.xml clean test verify
test-user-service: clean build-metadata-db build-user-service
mvn -f ./fda-user-service/pom.xml clean test verify
test-semantics-service: build-semantics-service
bash ./fda-semantics-service/test.sh
......
......@@ -45,6 +45,17 @@
"failureFactor" : 30,
"roles" : {
"realm" : [ {
"id" : "48f38342-1e3f-427a-995d-c436eaee65cb",
"name" : "default-user-handling",
"description" : "${default-user-handling}",
"composite" : true,
"composites" : {
"realm" : [ "modify-user-information" ]
},
"clientRole" : false,
"containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
"attributes" : { }
}, {
"id" : "5136d7a3-e3f0-4585-bacd-15cb8a56095c",
"name" : "escalated-container-handling",
"description" : "${escalated-container-handling}",
......@@ -123,7 +134,7 @@
"description" : "${default-researcher-roles}",
"composite" : true,
"composites" : {
"realm" : [ "default-table-handling", "default-container-handling", "default-query-handling", "default-database-handling", "default-identifier-handling" ]
"realm" : [ "default-table-handling", "default-container-handling", "default-query-handling", "default-user-handling", "default-database-handling", "default-identifier-handling" ]
},
"clientRole" : false,
"containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
......@@ -447,6 +458,14 @@
"clientRole" : false,
"containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
"attributes" : { }
}, {
"id" : "a2cc60df-d280-46c5-a539-92e2aa249b4a",
"name" : "modify-user-information",
"description" : "${modify-user-information}",
"composite" : false,
"clientRole" : false,
"containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
"attributes" : { }
}, {
"id" : "c367241f-b5b5-491f-84d5-07fe1bef3877",
"name" : "default-identifier-handling",
......@@ -843,7 +862,7 @@
"otpPolicyLookAheadWindow" : 1,
"otpPolicyPeriod" : 30,
"otpPolicyCodeReusable" : false,
"otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName" ],
"otpSupportedApplications" : [ "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName", "totpAppFreeOTPName" ],
"webAuthnPolicyRpEntityName" : "keycloak",
"webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
"webAuthnPolicyRpId" : "",
......@@ -1761,7 +1780,7 @@
"subType" : "anonymous",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper" ]
"allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ]
}
}, {
"id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1",
......@@ -1787,7 +1806,7 @@
"subType" : "authenticated",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper" ]
"allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper" ]
}
} ],
"org.keycloak.userprofile.UserProfileProvider" : [ {
......@@ -1845,7 +1864,7 @@
"internationalizationEnabled" : false,
"supportedLocales" : [ ],
"authenticationFlows" : [ {
"id" : "1f1eb5f9-0230-466f-91aa-be0419983e17",
"id" : "db0aeca3-8774-4c3d-a6b7-a29a7de63cf4",
"alias" : "Account verification options",
"description" : "Method with which to verity the existing account",
"providerId" : "basic-flow",
......@@ -1867,7 +1886,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "e7facc63-0292-4af3-9337-135b48f4b531",
"id" : "cfed2477-e59b-4b95-b76f-70d84e8c0876",
"alias" : "Authentication Options",
"description" : "Authentication options.",
"providerId" : "basic-flow",
......@@ -1896,7 +1915,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "3545c40f-56e7-4f27-ad58-599b49ce3142",
"id" : "0753142a-666c-4b86-8aed-e6930f4cfd9b",
"alias" : "Browser - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
......@@ -1918,7 +1937,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "5eb07c64-8922-46f5-859b-048b4d437914",
"id" : "f34f13eb-4053-452c-95d4-d11b2f38a679",
"alias" : "Direct Grant - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
......@@ -1940,7 +1959,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "d674029f-157a-46fa-b1ec-39e82b4426bf",
"id" : "899e0d91-28fa-4e3c-833b-fb21d3f59ef9",
"alias" : "First broker login - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
......@@ -1962,7 +1981,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "90b616c1-fda9-4598-a094-893e2beb17fa",
"id" : "57791f8b-44ec-4e33-a277-bc388e22770f",
"alias" : "Handle Existing Account",
"description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
"providerId" : "basic-flow",
......@@ -1984,7 +2003,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "fad9e269-be55-4d92-bca5-842fd9de849f",
"id" : "66f34e28-c468-42f0-a842-18e744d9774f",
"alias" : "Reset - Conditional OTP",
"description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
"providerId" : "basic-flow",
......@@ -2006,7 +2025,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "f707e941-eaf3-4c05-b2a7-67526d7a12f4",
"id" : "27738ff3-8b2c-498b-8303-eca7cd809f5a",
"alias" : "User creation or linking",
"description" : "Flow for the existing/non-existing user alternatives",
"providerId" : "basic-flow",
......@@ -2029,7 +2048,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "4e503594-a75c-462e-aefc-fdbef2cb1c71",
"id" : "272979c3-9993-42d3-a2e3-7fd8a5e872bb",
"alias" : "Verify Existing Account by Re-authentication",
"description" : "Reauthentication of existing account",
"providerId" : "basic-flow",
......@@ -2051,7 +2070,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "17536b8b-bccc-4fea-8a80-8aa9b8011892",
"id" : "537f7a1a-1c6a-444a-8c83-ed5401d4f00a",
"alias" : "browser",
"description" : "browser based authentication",
"providerId" : "basic-flow",
......@@ -2087,7 +2106,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "ba97bdce-4c2f-4991-bfec-57833cb5d1aa",
"id" : "87638583-1629-4879-8705-ddb97e61c57e",
"alias" : "clients",
"description" : "Base authentication for clients",
"providerId" : "client-flow",
......@@ -2123,7 +2142,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "8a0e40d3-ae9b-4785-866e-6e74a904b25d",
"id" : "de85f9a3-f505-4f4a-9f0f-23ad6a42c64b",
"alias" : "direct grant",
"description" : "OpenID Connect Resource Owner Grant",
"providerId" : "basic-flow",
......@@ -2152,7 +2171,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "b8b52271-d195-43e4-aff1-38b4d8109a78",
"id" : "74b10c28-424b-416c-9b09-1835418daafe",
"alias" : "docker auth",
"description" : "Used by Docker clients to authenticate against the IDP",
"providerId" : "basic-flow",
......@@ -2167,7 +2186,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "cd98a51e-4919-44ac-a616-10b74f24f63c",
"id" : "bf8aedfb-8645-4130-bf30-e04a9f351eea",
"alias" : "first broker login",
"description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"providerId" : "basic-flow",
......@@ -2190,7 +2209,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "70d9bb8f-db1a-4c50-916d-293c89809115",
"id" : "c3f6f1c8-2533-4e61-9e8f-89e5d4919923",
"alias" : "forms",
"description" : "Username, password, otp and other auth forms.",
"providerId" : "basic-flow",
......@@ -2212,7 +2231,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "098a8d3c-8b5f-4ea2-9aea-6f39cb6efece",
"id" : "ed4ab53a-4d51-4f0e-b2f6-e0ea7be307e7",
"alias" : "http challenge",
"description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
"providerId" : "basic-flow",
......@@ -2234,7 +2253,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "8181b950-1e18-4155-b09f-c5a9abddc3b5",
"id" : "1e8dc301-de23-400f-af1c-0df80fcec9b7",
"alias" : "registration",
"description" : "registration flow",
"providerId" : "basic-flow",
......@@ -2250,7 +2269,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "3301b0a6-7203-4768-81d9-624c4eb6fdfe",
"id" : "3359cf28-0d4b-407b-a291-65eec7879076",
"alias" : "registration form",
"description" : "registration form",
"providerId" : "form-flow",
......@@ -2286,7 +2305,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "374506b9-5eee-4199-b3d1-a82402d16334",
"id" : "76e815e3-344a-41dd-a593-a4c935218a61",
"alias" : "reset credentials",
"description" : "Reset credentials for a user if they forgot their password or something",
"providerId" : "basic-flow",
......@@ -2322,7 +2341,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "17ef89a8-d70f-4aca-8d08-d086e7423b5e",
"id" : "196d317e-c522-4058-b57c-2f527b3a139d",
"alias" : "saml ecp",
"description" : "SAML ECP Profile Authentication Flow",
"providerId" : "basic-flow",
......@@ -2338,13 +2357,13 @@
} ]
} ],
"authenticatorConfig" : [ {
"id" : "5545fd8f-21da-4c6d-9b01-85733268fd18",
"id" : "ebd93af1-fecc-40d7-bc18-453d7367e183",
"alias" : "create unique user config",
"config" : {
"require.password.update.after.registration" : "false"
}
}, {
"id" : "0b3921a6-d1fb-45ce-a8cb-d5cac4cc3d7f",
"id" : "da7de212-1212-48f7-8f75-d550888092b4",
"alias" : "review profile config",
"config" : {
"update.profile.on.first.login" : "missing"
......
......@@ -25,10 +25,6 @@ ENV METADATA_DB=fda
ENV METADATA_USERNAME=root
ENV METADATA_PASSWORD=dbrepo
ENV GATEWAY_ENDPOINT=https://gateway-service:9095
ENV KEYCLOAK_ADMIN=fda
ENV KEYCLOAK_ADMIN_PASSWORD=fda
ENV DBREPO_CLIENT_SECRET=client-secret
ENV CLIENT_ID=dbrepo-client
ENV JWT_ISSUER=http://localhost:8080/realms/dbrepo
ENV JWT_PUBKEY=public-key
ENV LOG_LEVEL=debug
......@@ -36,6 +32,7 @@ ENV KEY_ALIAS=user-service
ENV KEY_PASS=password
ENV KEY_STORE=./server.keystore
ENV KEY_STORE_PASS=password
ENV DEFAULT_ROLE=default-researcher-roles
WORKDIR /app
......
......@@ -2,6 +2,9 @@ package at.tuwien.endpoint;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.UserBriefDto;
import at.tuwien.api.user.UserDto;
import at.tuwien.api.user.UserUpdateDto;
import at.tuwien.config.AuthenticationConfig;
import at.tuwien.entities.auth.Realm;
import at.tuwien.entities.user.Role;
import at.tuwien.exception.*;
......@@ -15,11 +18,13 @@ 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.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.security.Principal;
import java.util.List;
import java.util.stream.Collectors;
......@@ -30,17 +35,19 @@ import java.util.stream.Collectors;
public class UserEndpoint {
private final UserMapper userMapper;
private final RoleService roleService;
private final UserService userService;
private final RealmService realmService;
private final RoleService roleService;
private final AuthenticationConfig authenticationConfig;
@Autowired
public UserEndpoint(UserMapper userMapper, UserService userService, RealmService realmService,
RoleService roleService) {
public UserEndpoint(UserMapper userMapper, RoleService roleService, UserService userService,
RealmService realmService, AuthenticationConfig authenticationConfig) {
this.userMapper = userMapper;
this.roleService = roleService;
this.userService = userService;
this.realmService = realmService;
this.roleService = roleService;
this.authenticationConfig = authenticationConfig;
}
@GetMapping
......@@ -66,11 +73,26 @@ public class UserEndpoint {
UserAlreadyExistsException, RoleNotFoundException {
log.debug("endpoint create a user, data={}", data);
final Realm realm = realmService.find("dbrepo");
final Role role = roleService.find("default-researcher-roles");
final Role role = roleService.find(authenticationConfig.getDefaultRole());
final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data, realm, role));
log.trace("create user resulted in dto {}", dto);
return ResponseEntity.status(HttpStatus.CREATED)
.body(dto);
}
@PutMapping
@Transactional
@PreAuthorize("hasAuthority('modify-user-information')")
@Timed(value = "user.modify", description = "Time needed to modify a user in the metadata database")
@Operation(summary = "Modify a user")
public ResponseEntity<UserDto> modify(@NotNull @Valid @RequestBody UserUpdateDto data,
@NotNull Principal principal)
throws UserNotFoundException {
log.debug("endpoint modify a user, data={}", data);
final UserDto dto = userMapper.userToUserDto(userService.modify(data, principal));
log.trace("modify user resulted in dto {}", dto);
return ResponseEntity.status(HttpStatus.ACCEPTED)
.body(dto);
}
}
......@@ -52,9 +52,7 @@ eureka:
fda:
ready.path: /ready
gateway.endpoint: "${GATEWAY_ENDPOINT}"
keycloak:
username: "${KEYCLOAK_ADMIN}"
password: "${KEYCLOAK_ADMIN_PASSWORD}"
default_role: "${DEFAULT_ROLE}"
jwt:
issuer: "${JWT_ISSUER}"
public_key: "${JWT_PUBKEY}"
\ No newline at end of file
......@@ -52,9 +52,7 @@ eureka:
fda:
ready.path: ./ready
gateway.endpoint: https://gateway-service:9095
keycloak:
username: fda
password: fda
default_role: default-researcher-roles
jwt:
issuer: https://localhost:8443/realms/dbrepo
public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB
\ No newline at end of file
......@@ -48,9 +48,7 @@ eureka:
fda:
ready.path: /ready
gateway.endpoint: "${GATEWAY_ENDPOINT}"
keycloak:
username: "${KEYCLOAK_ADMIN}"
password: "${KEYCLOAK_ADMIN_PASSWORD}"
default_role: "${DEFAULT_ROLE}"
jwt:
issuer: "${JWT_ISSUER}"
public_key: "${JWT_PUBKEY}"
package at.tuwien.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Getter
@Configuration
public class AuthenticationConfig {
@Value("${fda.default_role}")
private String defaultRole;
}
......@@ -16,12 +16,6 @@ public class GatewayConfig {
@Value("${fda.gateway.endpoint}")
private String gatewayEndpoint;
@Value("${fda.keycloak.username}")
private String keycloakUsername;
@Value("${fda.keycloak.password}")
private String keycloakPassword;
private final AuthenticationMapper authenticationMapper;
@Autowired
......
package at.tuwien.gateway;
import at.tuwien.api.auth.CreateUserDto;
import at.tuwien.api.auth.TokenDto;
import at.tuwien.exception.RemoteUnavailableException;
public interface GatewayServiceGateway {
TokenDto getToken() throws RemoteUnavailableException;
void createUser(String token, CreateUserDto data) throws RemoteUnavailableException;
}
package at.tuwien.gateway.impl;
import at.tuwien.api.auth.CreateUserDto;
import at.tuwien.api.auth.TokenDto;
import at.tuwien.config.GatewayConfig;
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.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
@Log4j2
@Service
public class GatewayServiceGatewayImpl implements GatewayServiceGateway {
private final RestTemplate restTemplate;
private final GatewayConfig gatewayConfig;
@Autowired
public GatewayServiceGatewayImpl(RestTemplate restTemplate,
GatewayConfig gatewayConfig) {
this.restTemplate = restTemplate;
this.gatewayConfig = gatewayConfig;
}
@Override
public TokenDto getToken() throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders();
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);
final ResponseEntity<TokenDto> response;
try {
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);
}
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
log.error("Failed to obtain admin token: credentials are invalid");
throw new RemoteUnavailableException("Failed to obtain admin token: credentials are invalid");
}
return response.getBody();
}
@Override
public void createUser(String token, CreateUserDto data) throws RemoteUnavailableException {
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(token);
final ResponseEntity<Void> response;
try {
response = restTemplate.exchange("/api/auth/admin/realms/dbrepo/users", HttpMethod.POST,
new HttpEntity<>(data, headers), Void.class);
} catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
log.error("Failed to create user: {}", e.getMessage());
throw new RemoteUnavailableException("Failed to create user", e);
}
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
log.error("Failed to create user: credentials are invalid");
throw new RemoteUnavailableException("Failed to create user: credentials are invalid");
}
}
}
......@@ -11,4 +11,6 @@ public interface UserRepository extends JpaRepository<User, String> {
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);
}
package at.tuwien.service;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.UserUpdateDto;
import at.tuwien.entities.auth.Realm;
import at.tuwien.entities.user.Role;
import at.tuwien.entities.user.User;
......@@ -8,6 +9,7 @@ import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.exception.UserAlreadyExistsException;
import at.tuwien.exception.UserNotFoundException;
import java.security.Principal;
import java.util.List;
public interface UserService {
......@@ -28,7 +30,10 @@ public interface UserService {
*/
User findByUsername(String username) throws UserNotFoundException;
User create(SignupRequestDto data, Realm realm, Role role) throws RemoteUnavailableException, UserNotFoundException, UserAlreadyExistsException;
User create(SignupRequestDto data, Realm realm, Role role) throws RemoteUnavailableException, UserNotFoundException,
UserAlreadyExistsException;
User modify(UserUpdateDto data, Principal principal) throws UserNotFoundException;
User find(String id) throws UserNotFoundException;
}
package at.tuwien.service.impl;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.UserUpdateDto;
import at.tuwien.entities.auth.Realm;
import at.tuwien.entities.user.Credential;
import at.tuwien.entities.user.Role;
......@@ -23,6 +24,7 @@ import org.springframework.stereotype.Service;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
......@@ -79,6 +81,11 @@ public class UserServiceImpl implements UserService {
log.error("User with username {} already exists", data.getUsername());
throw new UserAlreadyExistsException("User with username " + data.getUsername() + " already exists");
}
final Optional<User> optional2 = userRepository.findByEmail(data.getEmail());
if (optional2.isPresent()) {
log.error("User with email {} already exists", data.getUsername());
throw new UserAlreadyExistsException("User with email " + data.getUsername() + " already exists");
}
/* create secret */
final byte[] salt = getSalt();
final StringBuilder secretData = new StringBuilder("{\"value\":\"")
......@@ -114,6 +121,18 @@ public class UserServiceImpl implements UserService {
return user;
}
@Override
public User modify(UserUpdateDto data, Principal principal) throws UserNotFoundException {
/* check */
final User entity = findByUsername(principal.getName());
entity.setFirstname(data.getFirstname());
entity.setLastname(data.getLastname());
/* save */
final User user = userRepository.save(entity);
log.info("Modified user with id {}", user.getId());
return user;
}
@Override
public User find(String id) throws UserNotFoundException {
final Optional<User> optional = userRepository.findById(id);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment