diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java index 32221b2b73..e06fe523ee 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java @@ -19,21 +19,17 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections.ListUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.*; import org.thingsboard.server.common.data.id.*; -import org.thingsboard.server.common.data.kv.AttributeKvEntry; -import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; -import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.data.kv.*; import org.thingsboard.server.common.data.oauth2.*; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.exception.DataValidationException; @@ -47,6 +43,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -78,7 +75,7 @@ public class OAuth2ServiceImpl implements OAuth2Service { @Autowired private TenantService tenantService; - private final Map clientRegistrationsByRegistrationId = new ConcurrentHashMap<>(); + private final Map clientsParams = new ConcurrentHashMap<>(); private boolean isInstall() { @@ -90,21 +87,18 @@ public class OAuth2ServiceImpl implements OAuth2Service { public void init() { if (isInstall()) return; - OAuth2ClientsParams systemOAuth2ClientsParams = getSystemOAuth2ClientsParams(TenantId.SYS_TENANT_ID); - OAuth2ClientsParams tenantsOAuth2ClientsParams = getAllOAuth2ClientsParams(); - - Stream.concat( - systemOAuth2ClientsParams.getClientRegistrations().stream(), - tenantsOAuth2ClientsParams.getClientRegistrations().stream() - ) - .forEach(clientRegistration -> { - clientRegistrationsByRegistrationId.put(clientRegistration.getRegistrationId(), clientRegistration); - }); + Map allOAuth2ClientsParams = getAllOAuth2ClientsParams(); + + allOAuth2ClientsParams.forEach(clientsParams::put); } @Override public OAuth2ClientRegistration getClientRegistration(String registrationId) { - return clientRegistrationsByRegistrationId.get(registrationId); + return clientsParams.values().stream() + .flatMap(oAuth2ClientsParams -> oAuth2ClientsParams.getClientRegistrations().stream()) + .filter(clientRegistration -> registrationId.equals(clientRegistration.getRegistrationId())) + .findFirst() + .orElse(null); } @Override @@ -112,24 +106,26 @@ public class OAuth2ServiceImpl implements OAuth2Service { OAuth2ClientsParams oAuth2ClientsParams = getMergedOAuth2ClientsParams(domainName); return oAuth2ClientsParams != null && oAuth2ClientsParams.getClientRegistrations() != null ? oAuth2ClientsParams.getClientRegistrations().stream() - .map(clientRegistration -> { - OAuth2ClientInfo client = new OAuth2ClientInfo(); - client.setName(clientRegistration.getLoginButtonLabel()); - client.setUrl(String.format(OAUTH2_AUTHORIZATION_PATH_TEMPLATE, clientRegistration.getRegistrationId())); - client.setIcon(clientRegistration.getLoginButtonIcon()); - return client; - }) + .map(this::toClientInfo) .collect(Collectors.toList()) : Collections.emptyList() ; } + private OAuth2ClientInfo toClientInfo(OAuth2ClientRegistration clientRegistration) { + OAuth2ClientInfo client = new OAuth2ClientInfo(); + client.setName(clientRegistration.getLoginButtonLabel()); + client.setUrl(String.format(OAUTH2_AUTHORIZATION_PATH_TEMPLATE, clientRegistration.getRegistrationId())); + client.setIcon(clientRegistration.getLoginButtonIcon()); + return client; + } + @Override public OAuth2ClientsParams saveSystemOAuth2ClientsParams(OAuth2ClientsParams oAuth2ClientsParams) { // TODO check by registration ID in entities - for (OAuth2ClientRegistration clientRegistration : oAuth2ClientsParams.getClientRegistrations()) { - validator.accept(clientRegistration); - } + validate(oAuth2ClientsParams); + + AdminSettings clientRegistrationParamsSettings = new AdminSettings(); clientRegistrationParamsSettings.setKey(OAUTH2_CLIENT_REGISTRATIONS_PARAMS); ObjectNode clientRegistrationsNode = mapper.createObjectNode(); @@ -155,9 +151,7 @@ public class OAuth2ServiceImpl implements OAuth2Service { public OAuth2ClientsParams saveTenantOAuth2ClientsParams(TenantId tenantId, OAuth2ClientsParams oAuth2ClientsParams) { // TODO ask what if tenant saves config for several different domain names, do we need to check it // TODO check by registration ID in system - for (OAuth2ClientRegistration clientRegistration : oAuth2ClientsParams.getClientRegistrations()) { - validator.accept(clientRegistration); - } + validate(oAuth2ClientsParams); String clientRegistrationsKey = constructClientRegistrationsKey(oAuth2ClientsParams.getDomainName()); AdminSettings existentAdminSettingsByKey = adminSettingsService.findAdminSettingsByKey(tenantId, clientRegistrationsKey); if (StringUtils.isEmpty(oAuth2ClientsParams.getAdminSettingsId())) { @@ -211,6 +205,12 @@ public class OAuth2ServiceImpl implements OAuth2Service { return getTenantOAuth2ClientsParams(tenantId); } + private void validate(OAuth2ClientsParams oAuth2ClientsParams) { + for (OAuth2ClientRegistration clientRegistration : oAuth2ClientsParams.getClientRegistrations()) { + validator.accept(clientRegistration); + } + } + @Override public OAuth2ClientsParams getSystemOAuth2ClientsParams(TenantId tenantId) { AdminSettings oauth2ClientsParamsSettings = adminSettingsService.findAdminSettingsByKey(tenantId, OAUTH2_CLIENT_REGISTRATIONS_PARAMS); @@ -237,10 +237,22 @@ public class OAuth2ServiceImpl implements OAuth2Service { } } - private OAuth2ClientsParams getAllOAuth2ClientsParams() { - ListenableFuture jsonFuture = getOAuth2ClientsParamsAttribute(); + private Map getAllOAuth2ClientsParams() { + OAuth2ClientsParams systemOAuth2ClientsParams = getSystemOAuth2ClientsParams(TenantId.SYS_TENANT_ID); + ListenableFuture> jsonFuture = getAllOAuth2ClientsParamsAttribute(); try { - return Futures.transform(jsonFuture, this::constructOAuth2ClientsParams, MoreExecutors.directExecutor()).get(); + return Futures.transform(jsonFuture, + clientsParamsByKvEntryKey -> { + Map tenantClientParams = clientsParamsByKvEntryKey.entrySet().stream() + .collect(Collectors.toMap( + entry -> new TenantId(UUIDConverter.fromString(entry.getKey())), + entry -> constructOAuth2ClientsParams(entry.getValue()) + )); + tenantClientParams.put(TenantId.SYS_TENANT_ID, systemOAuth2ClientsParams); + return tenantClientParams; + }, + MoreExecutors.directExecutor() + ).get(); } catch (InterruptedException | ExecutionException e) { log.error("Failed to read OAuth2 Clients Params from attributes!", e); throw new RuntimeException("Failed to read OAuth2 Clients Params from attributes!", e); @@ -287,20 +299,20 @@ public class OAuth2ServiceImpl implements OAuth2Service { }, MoreExecutors.directExecutor()); } - private ListenableFuture getOAuth2ClientsParamsAttribute() { - ListenableFuture> attributeKvEntriesFuture; + private ListenableFuture> getAllOAuth2ClientsParamsAttribute() { + ListenableFuture> entityAttributeKvEntriesFuture; try { - attributeKvEntriesFuture = attributesService.findAllByAttributeKey(OAUTH2_CLIENT_REGISTRATIONS_PARAMS); + entityAttributeKvEntriesFuture = attributesService.findAllByAttributeKey(OAUTH2_CLIENT_REGISTRATIONS_PARAMS); } catch (Exception e) { log.error("Unable to read OAuth2 Clients Params from attributes!", e); throw new IncorrectParameterException("Unable to read OAuth2 Clients Params from attributes!"); } - return Futures.transform(attributeKvEntriesFuture, attributeKvEntries -> { + return Futures.transform(entityAttributeKvEntriesFuture, attributeKvEntries -> { if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) { - AttributeKvEntry kvEntry = attributeKvEntries.get(0); - return kvEntry.getValueAsString(); + return attributeKvEntries.stream() + .collect(Collectors.toMap(EntityAttributeKvEntry::getEntityId, EntityAttributeKvEntry::getValueAsString)); } else { - return ""; + return Collections.emptyMap(); } }, MoreExecutors.directExecutor()); }