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
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 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