1
2
3
4
5
6 package org.tailormap.api.security;
7
8 import java.io.Serial;
9 import java.io.Serializable;
10 import java.time.ZoneId;
11 import java.time.ZonedDateTime;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Objects;
17 import org.apache.commons.lang3.StringUtils;
18 import org.springframework.security.core.GrantedAuthority;
19 import org.springframework.security.core.authority.SimpleGrantedAuthority;
20 import org.springframework.security.core.userdetails.UserDetails;
21 import org.tailormap.api.persistence.Group;
22 import org.tailormap.api.persistence.User;
23 import org.tailormap.api.repository.GroupRepository;
24
25 public class TailormapUserDetails implements UserDetails {
26 public record UDAdditionalProperty(String key, Boolean isPublic, Object value) implements Serializable {}
27
28 @Serial
29 private static final long serialVersionUID = 2L;
30
31 private final Collection<GrantedAuthority> authorities;
32 private final String username;
33 private final String password;
34 private final ZonedDateTime validUntil;
35 private final boolean enabled;
36
37 private final List<UDAdditionalProperty> additionalProperties = new ArrayList<>();
38 private final List<UDAdditionalProperty> additionalGroupProperties = new ArrayList<>();
39
40 public TailormapUserDetails(User user, GroupRepository groupRepository) {
41 authorities = new HashSet<>();
42 user.getGroups().stream()
43 .map(Group::getName)
44 .map(SimpleGrantedAuthority::new)
45 .forEach(authorities::add);
46
47 user.getGroups().stream()
48 .map(Group::getAliasForGroup)
49 .filter(StringUtils::isNotBlank)
50 .map(SimpleGrantedAuthority::new)
51 .forEach(authorities::add);
52
53 username = user.getUsername();
54 password = user.getPassword();
55 validUntil = user.getValidUntil();
56 enabled = user.isEnabled();
57
58 user.getAdditionalProperties().stream()
59 .map(p -> new UDAdditionalProperty(p.getKey(), p.getIsPublic(), p.getValue()))
60 .forEach(additionalProperties::add);
61
62
63
64 groupRepository
65 .findAllById(
66 authorities.stream().map(GrantedAuthority::getAuthority).toList())
67 .stream()
68 .map(Group::getAdditionalProperties)
69 .filter(Objects::nonNull)
70 .flatMap(Collection::stream)
71 .map(p -> new UDAdditionalProperty(p.getKey(), p.getIsPublic(), p.getValue()))
72 .forEach(additionalGroupProperties::add);
73 }
74
75 @Override
76 public Collection<? extends GrantedAuthority> getAuthorities() {
77 return authorities;
78 }
79
80 @Override
81 public String getPassword() {
82 return password;
83 }
84
85 @Override
86 public String getUsername() {
87 return username;
88 }
89
90 @Override
91 public boolean isAccountNonExpired() {
92 return validUntil == null || validUntil.isAfter(ZonedDateTime.now(ZoneId.systemDefault()));
93 }
94
95 @Override
96 public boolean isEnabled() {
97 return enabled;
98 }
99
100 public List<UDAdditionalProperty> getAdditionalProperties() {
101 return additionalProperties;
102 }
103
104 public List<UDAdditionalProperty> getAdditionalGroupProperties() {
105 return additionalGroupProperties;
106 }
107
108 public boolean getBooleanUserProperty(String key) {
109 return additionalProperties.stream()
110 .filter(p -> p.key.equals(key))
111 .map(UDAdditionalProperty::value)
112 .map("true"::equals)
113 .findFirst()
114 .orElse(false);
115 }
116 }