2024-01-03 17:59:04 +00:00
|
|
|
package stirling.software.SPDF.config.security;
|
|
|
|
|
2024-09-05 22:24:38 +05:30
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
2024-01-03 17:59:04 +00:00
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
2024-05-12 19:58:34 +02:00
|
|
|
import org.springframework.context.MessageSource;
|
|
|
|
import org.springframework.context.i18n.LocaleContextHolder;
|
2024-01-03 17:59:04 +00:00
|
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
|
import org.springframework.security.core.Authentication;
|
|
|
|
import org.springframework.security.core.GrantedAuthority;
|
|
|
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
2024-09-13 16:42:38 +01:00
|
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
2024-08-16 12:57:37 +02:00
|
|
|
import org.springframework.security.core.session.SessionInformation;
|
2024-01-03 17:59:04 +00:00
|
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
2024-08-16 12:57:37 +02:00
|
|
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
2024-01-03 17:59:04 +00:00
|
|
|
import org.springframework.stereotype.Service;
|
2024-09-05 22:24:38 +05:30
|
|
|
|
2024-10-14 22:34:41 +01:00
|
|
|
import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
|
2024-10-20 13:30:58 +02:00
|
|
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
2024-08-16 12:57:37 +02:00
|
|
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
2024-01-03 17:59:04 +00:00
|
|
|
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
2024-05-12 19:58:34 +02:00
|
|
|
import stirling.software.SPDF.model.AuthenticationType;
|
2024-01-03 17:59:04 +00:00
|
|
|
import stirling.software.SPDF.model.Authority;
|
|
|
|
import stirling.software.SPDF.model.Role;
|
|
|
|
import stirling.software.SPDF.model.User;
|
2024-05-02 14:52:50 -06:00
|
|
|
import stirling.software.SPDF.repository.AuthorityRepository;
|
2024-01-03 17:59:04 +00:00
|
|
|
import stirling.software.SPDF.repository.UserRepository;
|
|
|
|
|
|
|
|
@Service
|
|
|
|
public class UserService implements UserServiceInterface {
|
|
|
|
|
|
|
|
@Autowired private UserRepository userRepository;
|
|
|
|
|
2024-05-02 14:52:50 -06:00
|
|
|
@Autowired private AuthorityRepository authorityRepository;
|
|
|
|
|
2024-01-03 17:59:04 +00:00
|
|
|
@Autowired private PasswordEncoder passwordEncoder;
|
|
|
|
|
2024-05-12 19:58:34 +02:00
|
|
|
@Autowired private MessageSource messageSource;
|
|
|
|
|
2024-08-16 12:57:37 +02:00
|
|
|
@Autowired private SessionPersistentRegistry sessionRegistry;
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
@Autowired DatabaseBackupInterface databaseBackupHelper;
|
|
|
|
|
2024-10-14 22:34:41 +01:00
|
|
|
|
2024-04-29 15:01:22 -06:00
|
|
|
// Handle OAUTH2 login and user auto creation.
|
2024-07-05 21:48:33 +02:00
|
|
|
public boolean processOAuth2PostLogin(String username, boolean autoCreateUser)
|
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
if (!isUsernameValid(username)) {
|
2024-05-12 19:58:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
2024-08-16 12:57:37 +02:00
|
|
|
Optional<User> existingUser = findByUsernameIgnoreCase(username);
|
2024-05-18 23:47:05 +02:00
|
|
|
if (existingUser.isPresent()) {
|
2024-04-29 15:01:22 -06:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (autoCreateUser) {
|
2024-05-12 19:58:34 +02:00
|
|
|
saveUser(username, AuthenticationType.OAUTH2);
|
2024-04-29 15:01:22 -06:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-01-03 17:59:04 +00:00
|
|
|
public Authentication getAuthentication(String apiKey) {
|
2024-08-19 16:02:40 +02:00
|
|
|
Optional<User> user = getUserByApiKey(apiKey);
|
|
|
|
if (!user.isPresent()) {
|
2024-01-03 17:59:04 +00:00
|
|
|
throw new UsernameNotFoundException("API key is not valid");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert the user into an Authentication object
|
|
|
|
return new UsernamePasswordAuthenticationToken(
|
|
|
|
user, // principal (typically the user)
|
|
|
|
null, // credentials (we don't expose the password or API key here)
|
2024-08-19 16:02:40 +02:00
|
|
|
getAuthorities(user.get()) // user's authorities (roles/permissions)
|
2024-01-03 17:59:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Collection<? extends GrantedAuthority> getAuthorities(User user) {
|
|
|
|
// Convert each Authority object into a SimpleGrantedAuthority object.
|
|
|
|
return user.getAuthorities().stream()
|
|
|
|
.map((Authority authority) -> new SimpleGrantedAuthority(authority.getAuthority()))
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
}
|
|
|
|
|
|
|
|
private String generateApiKey() {
|
|
|
|
String apiKey;
|
|
|
|
do {
|
|
|
|
apiKey = UUID.randomUUID().toString();
|
2024-08-19 16:02:40 +02:00
|
|
|
} while (userRepository.findByApiKey(apiKey).isPresent()); // Ensure uniqueness
|
2024-01-03 17:59:04 +00:00
|
|
|
return apiKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public User addApiKeyToUser(String username) {
|
2024-08-19 16:02:40 +02:00
|
|
|
Optional<User> user = findByUsernameIgnoreCase(username);
|
|
|
|
if (user.isPresent()) {
|
|
|
|
user.get().setApiKey(generateApiKey());
|
|
|
|
return userRepository.save(user.get());
|
|
|
|
}
|
|
|
|
throw new UsernameNotFoundException("User not found");
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public User refreshApiKeyForUser(String username) {
|
|
|
|
return addApiKeyToUser(username); // reuse the add API key method for refreshing
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getApiKeyForUser(String username) {
|
|
|
|
User user =
|
2024-08-16 12:57:37 +02:00
|
|
|
findByUsernameIgnoreCase(username)
|
2024-01-03 17:59:04 +00:00
|
|
|
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
|
|
|
return user.getApiKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isValidApiKey(String apiKey) {
|
2024-08-19 16:02:40 +02:00
|
|
|
return userRepository.findByApiKey(apiKey).isPresent();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-08-19 16:02:40 +02:00
|
|
|
public Optional<User> getUserByApiKey(String apiKey) {
|
2024-01-03 17:59:04 +00:00
|
|
|
return userRepository.findByApiKey(apiKey);
|
|
|
|
}
|
|
|
|
|
2024-08-19 16:02:40 +02:00
|
|
|
public Optional<User> loadUserByApiKey(String apiKey) {
|
|
|
|
Optional<User> user = userRepository.findByApiKey(apiKey);
|
|
|
|
|
|
|
|
if (user.isPresent()) {
|
|
|
|
return user;
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
return null; // or throw an exception
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean validateApiKeyForUser(String username, String apiKey) {
|
2024-08-16 12:57:37 +02:00
|
|
|
Optional<User> userOpt = findByUsernameIgnoreCase(username);
|
2024-05-18 23:47:05 +02:00
|
|
|
return userOpt.isPresent() && apiKey.equals(userOpt.get().getApiKey());
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-05-12 19:58:34 +02:00
|
|
|
public void saveUser(String username, AuthenticationType authenticationType)
|
2024-07-05 21:48:33 +02:00
|
|
|
throws IllegalArgumentException, IOException {
|
2024-08-16 12:57:37 +02:00
|
|
|
saveUser(username, authenticationType, Role.USER.getRoleId());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void saveUser(String username, AuthenticationType authenticationType, String role)
|
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
if (!isUsernameValid(username)) {
|
|
|
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
|
|
|
}
|
2024-01-03 17:59:04 +00:00
|
|
|
User user = new User();
|
2024-05-18 23:47:05 +02:00
|
|
|
user.setUsername(username);
|
2024-05-12 19:58:34 +02:00
|
|
|
user.setEnabled(true);
|
|
|
|
user.setFirstLogin(false);
|
2024-08-16 12:57:37 +02:00
|
|
|
user.addAuthority(new Authority(role, user));
|
2024-05-12 19:58:34 +02:00
|
|
|
user.setAuthenticationType(authenticationType);
|
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-05-12 19:58:34 +02:00
|
|
|
}
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
public void saveUser(String username, String password)
|
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
if (!isUsernameValid(username)) {
|
|
|
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
|
|
|
}
|
2024-05-12 19:58:34 +02:00
|
|
|
User user = new User();
|
2024-05-18 23:47:05 +02:00
|
|
|
user.setUsername(username);
|
2024-01-03 17:59:04 +00:00
|
|
|
user.setPassword(passwordEncoder.encode(password));
|
|
|
|
user.setEnabled(true);
|
2024-05-12 19:58:34 +02:00
|
|
|
user.setAuthenticationType(AuthenticationType.WEB);
|
2024-01-03 17:59:04 +00:00
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-05-12 19:58:34 +02:00
|
|
|
public void saveUser(String username, String password, String role, boolean firstLogin)
|
2024-07-05 21:48:33 +02:00
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
if (!isUsernameValid(username)) {
|
|
|
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
|
|
|
}
|
2024-01-03 17:59:04 +00:00
|
|
|
User user = new User();
|
2024-05-18 23:47:05 +02:00
|
|
|
user.setUsername(username);
|
2024-01-03 17:59:04 +00:00
|
|
|
user.setPassword(passwordEncoder.encode(password));
|
|
|
|
user.addAuthority(new Authority(role, user));
|
|
|
|
user.setEnabled(true);
|
2024-05-12 19:58:34 +02:00
|
|
|
user.setAuthenticationType(AuthenticationType.WEB);
|
2024-01-03 17:59:04 +00:00
|
|
|
user.setFirstLogin(firstLogin);
|
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-05-12 19:58:34 +02:00
|
|
|
public void saveUser(String username, String password, String role)
|
2024-07-05 21:48:33 +02:00
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
saveUser(username, password, role, false);
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void deleteUser(String username) {
|
2024-08-16 12:57:37 +02:00
|
|
|
Optional<User> userOpt = findByUsernameIgnoreCase(username);
|
2024-01-03 17:59:04 +00:00
|
|
|
if (userOpt.isPresent()) {
|
|
|
|
for (Authority authority : userOpt.get().getAuthorities()) {
|
|
|
|
if (authority.getAuthority().equals(Role.INTERNAL_API_USER.getRoleId())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
userRepository.delete(userOpt.get());
|
|
|
|
}
|
2024-08-16 12:57:37 +02:00
|
|
|
invalidateUserSessions(username);
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean usernameExists(String username) {
|
2024-08-16 12:57:37 +02:00
|
|
|
return findByUsername(username).isPresent();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-14 23:07:03 +02:00
|
|
|
public boolean usernameExistsIgnoreCase(String username) {
|
2024-08-16 12:57:37 +02:00
|
|
|
return findByUsernameIgnoreCase(username).isPresent();
|
2024-04-14 23:07:03 +02:00
|
|
|
}
|
|
|
|
|
2024-01-03 17:59:04 +00:00
|
|
|
public boolean hasUsers() {
|
2024-05-19 10:52:11 +02:00
|
|
|
long userCount = userRepository.count();
|
2024-08-16 12:57:37 +02:00
|
|
|
if (findByUsernameIgnoreCase(Role.INTERNAL_API_USER.getRoleId()).isPresent()) {
|
2024-05-19 10:52:11 +02:00
|
|
|
userCount -= 1;
|
|
|
|
}
|
|
|
|
return userCount > 0;
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
public void updateUserSettings(String username, Map<String, String> updates)
|
|
|
|
throws IOException {
|
2024-08-23 23:37:45 +03:00
|
|
|
Optional<User> userOpt = findByUsernameIgnoreCaseWithSettings(username);
|
2024-01-03 17:59:04 +00:00
|
|
|
if (userOpt.isPresent()) {
|
|
|
|
User user = userOpt.get();
|
|
|
|
Map<String, String> settingsMap = user.getSettings();
|
|
|
|
|
|
|
|
if (settingsMap == null) {
|
2024-05-18 23:47:05 +02:00
|
|
|
settingsMap = new HashMap<>();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
settingsMap.clear();
|
|
|
|
settingsMap.putAll(updates);
|
|
|
|
user.setSettings(settingsMap);
|
|
|
|
|
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Optional<User> findByUsername(String username) {
|
|
|
|
return userRepository.findByUsername(username);
|
|
|
|
}
|
|
|
|
|
2024-03-13 23:09:16 +01:00
|
|
|
public Optional<User> findByUsernameIgnoreCase(String username) {
|
|
|
|
return userRepository.findByUsernameIgnoreCase(username);
|
|
|
|
}
|
|
|
|
|
2024-08-23 23:37:45 +03:00
|
|
|
public Optional<User> findByUsernameIgnoreCaseWithSettings(String username) {
|
|
|
|
return userRepository.findByUsernameIgnoreCaseWithSettings(username);
|
|
|
|
}
|
|
|
|
|
2024-05-02 14:52:50 -06:00
|
|
|
public Authority findRole(User user) {
|
|
|
|
return authorityRepository.findByUserId(user.getId());
|
|
|
|
}
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
public void changeUsername(User user, String newUsername)
|
|
|
|
throws IllegalArgumentException, IOException {
|
2024-05-18 23:47:05 +02:00
|
|
|
if (!isUsernameValid(newUsername)) {
|
|
|
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
|
|
|
}
|
|
|
|
user.setUsername(newUsername);
|
2024-01-03 17:59:04 +00:00
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
public void changePassword(User user, String newPassword) throws IOException {
|
2024-01-03 17:59:04 +00:00
|
|
|
user.setPassword(passwordEncoder.encode(newPassword));
|
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 21:48:33 +02:00
|
|
|
public void changeFirstUse(User user, boolean firstUse) throws IOException {
|
2024-01-03 17:59:04 +00:00
|
|
|
user.setFirstLogin(firstUse);
|
|
|
|
userRepository.save(user);
|
2024-07-05 21:48:33 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|
|
|
|
|
2024-08-16 12:57:37 +02:00
|
|
|
public void changeRole(User user, String newRole) throws IOException {
|
2024-05-02 14:52:50 -06:00
|
|
|
Authority userAuthority = this.findRole(user);
|
|
|
|
userAuthority.setAuthority(newRole);
|
|
|
|
authorityRepository.save(userAuthority);
|
2024-08-16 12:57:37 +02:00
|
|
|
databaseBackupHelper.exportDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void changeUserEnabled(User user, Boolean enbeled) throws IOException {
|
|
|
|
user.setEnabled(enbeled);
|
|
|
|
userRepository.save(user);
|
|
|
|
databaseBackupHelper.exportDatabase();
|
2024-05-02 14:52:50 -06:00
|
|
|
}
|
|
|
|
|
2024-01-03 17:59:04 +00:00
|
|
|
public boolean isPasswordCorrect(User user, String currentPassword) {
|
|
|
|
return passwordEncoder.matches(currentPassword, user.getPassword());
|
|
|
|
}
|
2024-03-13 23:09:16 +01:00
|
|
|
|
|
|
|
public boolean isUsernameValid(String username) {
|
2024-05-12 19:58:34 +02:00
|
|
|
// Checks whether the simple username is formatted correctly
|
|
|
|
boolean isValidSimpleUsername =
|
|
|
|
username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._+-]*[a-zA-Z0-9]$");
|
|
|
|
// Checks whether the email address is formatted correctly
|
|
|
|
boolean isValidEmail =
|
|
|
|
username.matches(
|
|
|
|
"^(?=.{1,64}@)[A-Za-z0-9]+(\\.[A-Za-z0-9_+.-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$");
|
|
|
|
return isValidSimpleUsername || isValidEmail;
|
|
|
|
}
|
|
|
|
|
2024-05-18 23:47:05 +02:00
|
|
|
private String getInvalidUsernameMessage() {
|
|
|
|
return messageSource.getMessage(
|
|
|
|
"invalidUsernameMessage", null, LocaleContextHolder.getLocale());
|
2024-05-12 19:58:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasPassword(String username) {
|
2024-08-16 12:57:37 +02:00
|
|
|
Optional<User> user = findByUsernameIgnoreCase(username);
|
2024-05-18 23:47:05 +02:00
|
|
|
return user.isPresent() && user.get().hasPassword();
|
2024-05-12 19:58:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isAuthenticationTypeByUsername(
|
|
|
|
String username, AuthenticationType authenticationType) {
|
2024-08-16 12:57:37 +02:00
|
|
|
Optional<User> user = findByUsernameIgnoreCase(username);
|
2024-05-18 23:47:05 +02:00
|
|
|
return user.isPresent()
|
|
|
|
&& authenticationType.name().equalsIgnoreCase(user.get().getAuthenticationType());
|
2024-03-13 23:09:16 +01:00
|
|
|
}
|
2024-08-16 12:57:37 +02:00
|
|
|
|
|
|
|
public boolean isUserDisabled(String username) {
|
|
|
|
Optional<User> userOpt = findByUsernameIgnoreCase(username);
|
|
|
|
return userOpt.map(user -> !user.isEnabled()).orElse(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void invalidateUserSessions(String username) {
|
|
|
|
String usernameP = "";
|
|
|
|
for (Object principal : sessionRegistry.getAllPrincipals()) {
|
|
|
|
for (SessionInformation sessionsInformation :
|
|
|
|
sessionRegistry.getAllSessions(principal, false)) {
|
|
|
|
if (principal instanceof UserDetails) {
|
|
|
|
UserDetails userDetails = (UserDetails) principal;
|
|
|
|
usernameP = userDetails.getUsername();
|
|
|
|
} else if (principal instanceof OAuth2User) {
|
|
|
|
OAuth2User oAuth2User = (OAuth2User) principal;
|
|
|
|
usernameP = oAuth2User.getName();
|
2024-10-20 13:30:58 +02:00
|
|
|
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
|
|
|
|
CustomSaml2AuthenticatedPrincipal saml2User =
|
|
|
|
(CustomSaml2AuthenticatedPrincipal) principal;
|
|
|
|
usernameP = saml2User.getName();
|
2024-08-16 12:57:37 +02:00
|
|
|
} else if (principal instanceof String) {
|
|
|
|
usernameP = (String) principal;
|
|
|
|
}
|
|
|
|
if (usernameP.equalsIgnoreCase(username)) {
|
|
|
|
sessionRegistry.expireSession(sessionsInformation.getSessionId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-09-13 16:42:38 +01:00
|
|
|
|
|
|
|
public String getCurrentUsername() {
|
|
|
|
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
|
|
|
|
|
|
if (principal instanceof UserDetails) {
|
|
|
|
return ((UserDetails) principal).getUsername();
|
|
|
|
} else {
|
|
|
|
return principal.toString();
|
|
|
|
}
|
|
|
|
}
|
2024-10-22 00:42:17 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public long getTotalUsersCount() {
|
|
|
|
return userRepository.count();
|
|
|
|
}
|
2024-01-03 17:59:04 +00:00
|
|
|
}
|