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

Adding default roles works

parent 0951c7fc
Branches
Tags
2 merge requests!163Relase 1.3.0,!155Added readme to authentication service and added eureka service
Showing
with 213 additions and 19 deletions
package at.tuwien.entities.user;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
@Data
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EntityListeners(AuditingEntityListener.class)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "keycloak_role")
public class Role {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(generator = "role-uuid")
@GenericGenerator(name = "role-uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
private String id;
@Column(name = "NAME", nullable = false)
private String name;
@Column(name = "REALM_ID", nullable = false)
private String realmId;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "user_role_mapping",
joinColumns = {
@JoinColumn(name = "ROLE_ID", referencedColumnName = "ID", insertable = false, updatable = false),
},
inverseJoinColumns = {
@JoinColumn(name = "USER_ID", referencedColumnName = "ID", insertable = false, updatable = false),
})
private User user;
}
package at.tuwien.entities.user;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
@Data
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
@IdClass(RoleMappingKey.class)
@EntityListeners(AuditingEntityListener.class)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "user_role_mapping")
public class RoleMapping {
@Id
@EqualsAndHashCode.Include
@Column(name = "USER_ID", nullable = false)
private String userId;
@Id
@EqualsAndHashCode.Include
@Column(name = "ROLE_ID", nullable = false)
private String roleId;
}
package at.tuwien.entities.user;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode
public class RoleMappingKey implements Serializable {
private String userId;
private String roleId;
}
......@@ -58,6 +58,11 @@ public class User {
@Column(nullable = false)
private String databasePassword;
@Column(nullable = false)
@ToString.Exclude
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private List<Role> roles;
@Column(nullable = false)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private List<Credential> credentials;
......
......@@ -10,7 +10,7 @@ export function authenticate (clientSecret, username, password) {
password,
grant_type: 'password',
client_secret: clientSecret,
scope: 'openid roles'
scope: 'openid profile roles'
}
return axios.post('/api/auth/realms/dbrepo/protocol/openid-connect/token', qs.stringify(payload), {
headers: { ContentType: 'application/form-data' }
......
......@@ -3,12 +3,11 @@ package at.tuwien.endpoint;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.api.user.UserBriefDto;
import at.tuwien.entities.auth.Realm;
import at.tuwien.exception.RealmNotFoundException;
import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.exception.UserAlreadyExistsException;
import at.tuwien.exception.UserNotFoundException;
import at.tuwien.entities.user.Role;
import at.tuwien.exception.*;
import at.tuwien.mapper.UserMapper;
import at.tuwien.service.RealmService;
import at.tuwien.service.RoleService;
import at.tuwien.service.UserService;
import io.micrometer.core.annotation.Timed;
import io.swagger.v3.oas.annotations.Operation;
......@@ -33,12 +32,15 @@ public class UserEndpoint {
private final UserMapper userMapper;
private final UserService userService;
private final RealmService realmService;
private final RoleService roleService;
@Autowired
public UserEndpoint(UserMapper userMapper, UserService userService, RealmService realmService) {
public UserEndpoint(UserMapper userMapper, UserService userService, RealmService realmService,
RoleService roleService) {
this.userMapper = userMapper;
this.userService = userService;
this.realmService = realmService;
this.roleService = roleService;
}
@GetMapping
......@@ -61,10 +63,11 @@ public class UserEndpoint {
@Operation(summary = "Create a user")
public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody SignupRequestDto data)
throws UserNotFoundException, RemoteUnavailableException, RealmNotFoundException,
UserAlreadyExistsException {
UserAlreadyExistsException, RoleNotFoundException {
log.debug("endpoint create a user, data={}", data);
final Realm realm = realmService.find("dbrepo");
final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data, realm));
final Role role = roleService.find("default-researcher-roles");
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);
......
package at.tuwien.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class RoleNotFoundException extends Exception {
public RoleNotFoundException(String msg) {
super(msg);
}
public RoleNotFoundException(String msg, Throwable thr) {
super(msg, thr);
}
public RoleNotFoundException(Throwable thr) {
super(thr);
}
}
package at.tuwien.repository.jpa;
import at.tuwien.entities.user.RoleMapping;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface RoleMappingRepository extends JpaRepository<RoleMapping, String> {
}
package at.tuwien.repository.jpa;
import at.tuwien.entities.user.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface RoleRepository extends JpaRepository<Role, String> {
Optional<Role> findByName(String name);
}
package at.tuwien.service;
import at.tuwien.entities.user.Role;
import at.tuwien.exception.RoleNotFoundException;
public interface RoleService {
Role find(String name) throws RoleNotFoundException;
}
......@@ -2,6 +2,7 @@ package at.tuwien.service;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.entities.auth.Realm;
import at.tuwien.entities.user.Role;
import at.tuwien.entities.user.User;
import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.exception.UserAlreadyExistsException;
......@@ -27,7 +28,7 @@ public interface UserService {
*/
User findByUsername(String username) throws UserNotFoundException;
User create(SignupRequestDto data, Realm realm) throws RemoteUnavailableException, UserNotFoundException, UserAlreadyExistsException;
User create(SignupRequestDto data, Realm realm, Role role) throws RemoteUnavailableException, UserNotFoundException, UserAlreadyExistsException;
User find(String id) throws UserNotFoundException;
}
package at.tuwien.service.impl;
import at.tuwien.entities.user.Role;
import at.tuwien.exception.RoleNotFoundException;
import at.tuwien.repository.jpa.RoleRepository;
import at.tuwien.service.RoleService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Log4j2
@Service
public class RoleServiceImpl implements RoleService {
private final RoleRepository roleRepository;
@Autowired
public RoleServiceImpl(RoleRepository roleRepository) {
this.roleRepository = roleRepository;
}
@Override
public Role find(String name) throws RoleNotFoundException {
final Optional<Role> optional = roleRepository.findByName(name);
if (optional.isEmpty()) {
log.error("Failed to find role with name {}", name);
throw new RoleNotFoundException("Failed to find role with name " + name);
}
final Role role = optional.get();
log.trace("found role {}", role);
return role;
}
}
......@@ -3,12 +3,15 @@ package at.tuwien.service.impl;
import at.tuwien.api.auth.SignupRequestDto;
import at.tuwien.entities.auth.Realm;
import at.tuwien.entities.user.Credential;
import at.tuwien.entities.user.Role;
import at.tuwien.entities.user.RoleMapping;
import at.tuwien.entities.user.User;
import at.tuwien.exception.RemoteUnavailableException;
import at.tuwien.exception.UserAlreadyExistsException;
import at.tuwien.exception.UserNotFoundException;
import at.tuwien.mapper.UserMapper;
import at.tuwien.repository.jpa.CredentialRepository;
import at.tuwien.repository.jpa.RoleMappingRepository;
import at.tuwien.repository.jpa.UserRepository;
import at.tuwien.service.UserService;
import lombok.extern.log4j.Log4j2;
......@@ -41,13 +44,15 @@ public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
private final UserRepository userRepository;
private final CredentialRepository credentialRepository;
private final RoleMappingRepository roleMappingRepository;
@Autowired
public UserServiceImpl(UserMapper userMapper, UserRepository userRepository,
CredentialRepository credentialRepository) {
CredentialRepository credentialRepository, RoleMappingRepository roleMappingRepository) {
this.userMapper = userMapper;
this.userRepository = userRepository;
this.credentialRepository = credentialRepository;
this.roleMappingRepository = roleMappingRepository;
}
@Override
......@@ -66,7 +71,7 @@ public class UserServiceImpl implements UserService {
}
@Override
public User create(SignupRequestDto data, Realm realm) throws RemoteUnavailableException, UserNotFoundException,
public User create(SignupRequestDto data, Realm realm, Role role) throws RemoteUnavailableException, UserNotFoundException,
UserAlreadyExistsException {
/* check */
final Optional<User> optional = userRepository.findByUsername(data.getUsername());
......@@ -75,13 +80,6 @@ public class UserServiceImpl implements UserService {
throw new UserAlreadyExistsException("User with username " + data.getUsername() + " already exists");
}
/* create secret */
/* save */
final User tmp = userMapper.signupRequestDtoToUser(data);
tmp.setEmailVerified(false);
tmp.setEnabled(true);
tmp.setRealmId(realm.getId());
tmp.setCreatedTimestamp(Instant.now().toEpochMilli());
final byte[] salt = getSalt();
final StringBuilder secretData = new StringBuilder("{\"value\":\"")
.append(encodedCredential(data.getPassword(), DEFAULT_ITERATIONS, salt, DERIVED_KEY_SIZE))
......@@ -95,10 +93,22 @@ public class UserServiceImpl implements UserService {
.priority(10)
.credentialData("{\"hashIterations\":" + DEFAULT_ITERATIONS + ",\"algorithm\":\"" + ID + "\",\"additionalParameters\":{}}")
.build();
/* save */
final User tmp = userMapper.signupRequestDtoToUser(data);
tmp.setEmailVerified(false);
tmp.setEnabled(true);
tmp.setRealmId(realm.getId());
tmp.setCreatedTimestamp(Instant.now().toEpochMilli());
final User user = userRepository.save(tmp);
entity.setUserId(user.getId());
final Credential credential = credentialRepository.save(entity);
user.setCredentials(List.of(credential));
final RoleMapping tmp2 = RoleMapping.builder()
.userId(user.getId())
.roleId(role.getId())
.build();
roleMappingRepository.save(tmp2);
user.setRoles(List.of(role));
log.info("Created user with id {}", user.getId());
log.debug("created user {}", user);
return user;
......@@ -116,7 +126,6 @@ public class UserServiceImpl implements UserService {
private String encodedCredential(String rawPassword, int iterations, byte[] salt, int derivedKeySize) {
final String rawPasswordWithPadding = PaddingUtils.padding(rawPassword, MAX_PADDING_LENGTH);
log.trace("padding: {}", rawPasswordWithPadding);
final KeySpec spec = new PBEKeySpec(rawPasswordWithPadding.toCharArray(), salt, iterations, derivedKeySize);
try {
byte[] key = getSecretKeyFactory().generateSecret(spec).getEncoded();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment