Allow to pass several domains for oauth2 config (for sys_admin only)
This commit is contained in:
parent
997821591a
commit
d22237796e
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.common.data.oauth2;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode
|
||||
@Data
|
||||
@ToString
|
||||
@Builder(toBuilder = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OAuth2ClientsDomainParams {
|
||||
private String domainName;
|
||||
private String adminSettingsId;
|
||||
|
||||
private List<OAuth2ClientRegistration> clientRegistrations;
|
||||
}
|
||||
@ -26,8 +26,5 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OAuth2ClientsParams {
|
||||
private String domainName;
|
||||
private String adminSettingsId;
|
||||
|
||||
private List<OAuth2ClientRegistration> clientRegistrations;
|
||||
private List<OAuth2ClientsDomainParams> clientsDomainsParams;
|
||||
}
|
||||
@ -47,6 +47,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -79,7 +80,6 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
return environment.acceptsProfiles("install");
|
||||
}
|
||||
|
||||
// TODO do I need to add a field that invalidates cache in case write to cache fails after successful saving in DB?
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (isInstall()) return;
|
||||
@ -94,7 +94,7 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
return clientsParams.entrySet().stream()
|
||||
.map(entry -> {
|
||||
TenantId tenantId = entry.getKey();
|
||||
OAuth2ClientRegistration clientRegistration = entry.getValue().getClientRegistrations().stream()
|
||||
OAuth2ClientRegistration clientRegistration = toClientRegistrationStream(entry.getValue())
|
||||
.filter(registration -> registrationId.equals(registration.getRegistrationId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
@ -115,9 +115,9 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
|
||||
@Override
|
||||
public List<OAuth2ClientInfo> getOAuth2Clients(String domainName) {
|
||||
OAuth2ClientsParams oAuth2ClientsParams = getMergedOAuth2ClientsParams(domainName);
|
||||
return oAuth2ClientsParams != null && oAuth2ClientsParams.getClientRegistrations() != null ?
|
||||
oAuth2ClientsParams.getClientRegistrations().stream()
|
||||
OAuth2ClientsDomainParams oAuth2ClientsDomainParams = getMergedOAuth2ClientsParams(domainName);
|
||||
return oAuth2ClientsDomainParams != null && oAuth2ClientsDomainParams.getClientRegistrations() != null ?
|
||||
oAuth2ClientsDomainParams.getClientRegistrations().stream()
|
||||
.map(this::toClientInfo)
|
||||
.collect(Collectors.toList())
|
||||
: Collections.emptyList()
|
||||
@ -150,15 +150,19 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
|
||||
@Override
|
||||
public OAuth2ClientsParams saveTenantOAuth2ClientsParams(TenantId tenantId, OAuth2ClientsParams oAuth2ClientsParams) {
|
||||
// TODO what if tenant saves config for several different domain names, do we need to check it
|
||||
if (oAuth2ClientsParams.getClientsDomainsParams().size() != 1) {
|
||||
throw new DataValidationException("Tenant can configure OAuth2 only for one domain!");
|
||||
}
|
||||
validate(oAuth2ClientsParams);
|
||||
|
||||
validateRegistrationIdUniqueness(oAuth2ClientsParams, tenantId);
|
||||
cacheWriteLock.lock();
|
||||
try {
|
||||
validateRegistrationIdUniqueness(oAuth2ClientsParams, tenantId);
|
||||
String adminSettingsId = processTenantAdminSettings(tenantId, oAuth2ClientsParams.getDomainName(), oAuth2ClientsParams.getAdminSettingsId());
|
||||
oAuth2ClientsParams.setAdminSettingsId(adminSettingsId);
|
||||
|
||||
OAuth2ClientsDomainParams oAuth2ClientsDomainParams = oAuth2ClientsParams.getClientsDomainsParams().get(0);
|
||||
String adminSettingsId = processTenantAdminSettings(tenantId, oAuth2ClientsDomainParams.getDomainName(), oAuth2ClientsDomainParams.getAdminSettingsId());
|
||||
oAuth2ClientsDomainParams.setAdminSettingsId(adminSettingsId);
|
||||
|
||||
List<AttributeKvEntry> attributes = createOAuth2ClientsParamsAttributes(oAuth2ClientsParams);
|
||||
try {
|
||||
@ -247,11 +251,20 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
}
|
||||
|
||||
private void validateRegistrationIdUniqueness(OAuth2ClientsParams inputOAuth2ClientsParams, TenantId tenantId) {
|
||||
inputOAuth2ClientsParams.getClientRegistrations().stream()
|
||||
long distinctRegistrationIds = toClientRegistrationStream(inputOAuth2ClientsParams)
|
||||
.map(OAuth2ClientRegistration::getRegistrationId)
|
||||
.distinct()
|
||||
.count();
|
||||
long actualRegistrationIds = toClientRegistrationStream(inputOAuth2ClientsParams).count();
|
||||
if (distinctRegistrationIds != actualRegistrationIds) {
|
||||
throw new DataValidationException("All registration IDs should be unique!");
|
||||
}
|
||||
|
||||
toClientRegistrationStream(inputOAuth2ClientsParams)
|
||||
.map(OAuth2ClientRegistration::getRegistrationId)
|
||||
.forEach(registrationId -> {
|
||||
clientsParams.forEach((paramsTenantId, oAuth2ClientsParams) -> {
|
||||
boolean registrationExists = oAuth2ClientsParams.getClientRegistrations().stream()
|
||||
boolean registrationExists = toClientRegistrationStream(oAuth2ClientsParams)
|
||||
.map(OAuth2ClientRegistration::getRegistrationId)
|
||||
.anyMatch(registrationId::equals);
|
||||
if (registrationExists && !tenantId.equals(paramsTenantId)) {
|
||||
@ -263,8 +276,27 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
}
|
||||
|
||||
private void validate(OAuth2ClientsParams oAuth2ClientsParams) {
|
||||
for (OAuth2ClientRegistration clientRegistration : oAuth2ClientsParams.getClientRegistrations()) {
|
||||
validator.accept(clientRegistration);
|
||||
validateDomainNames(oAuth2ClientsParams);
|
||||
|
||||
toClientRegistrationStream(oAuth2ClientsParams)
|
||||
.forEach(validator);
|
||||
}
|
||||
|
||||
private void validateDomainNames(OAuth2ClientsParams oAuth2ClientsParams) {
|
||||
oAuth2ClientsParams.getClientsDomainsParams()
|
||||
.forEach(oAuth2ClientsDomainParams -> {
|
||||
if (StringUtils.isEmpty(oAuth2ClientsDomainParams.getDomainName())) {
|
||||
throw new DataValidationException("Domain name should be specified!");
|
||||
}
|
||||
});
|
||||
|
||||
long distinctDomainNames = oAuth2ClientsParams.getClientsDomainsParams().stream()
|
||||
.map(OAuth2ClientsDomainParams::getDomainName)
|
||||
.distinct()
|
||||
.count();
|
||||
long actualDomainNames = oAuth2ClientsParams.getClientsDomainsParams().size();
|
||||
if (distinctDomainNames != actualDomainNames) {
|
||||
throw new DataValidationException("All domain names should be unique!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,7 +332,9 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
entry -> constructOAuth2ClientsParams(entry.getValue())
|
||||
))
|
||||
: new HashMap<>();
|
||||
if (systemOAuth2ClientsParams.getClientsDomainsParams() != null) {
|
||||
tenantClientParams.put(TenantId.SYS_TENANT_ID, systemOAuth2ClientsParams);
|
||||
}
|
||||
return tenantClientParams;
|
||||
},
|
||||
MoreExecutors.directExecutor()
|
||||
@ -314,13 +348,13 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
@Override
|
||||
public void deleteTenantOAuth2ClientsParams(TenantId tenantId) {
|
||||
OAuth2ClientsParams params = getTenantOAuth2ClientsParams(tenantId);
|
||||
if (!StringUtils.isEmpty(params.getDomainName())) {
|
||||
String settingsKey = constructAdminSettingsDomainKey(params.getDomainName());
|
||||
if (params == null) return;
|
||||
OAuth2ClientsDomainParams domainParams = params.getClientsDomainsParams().get(0);
|
||||
String settingsKey = constructAdminSettingsDomainKey(domainParams.getDomainName());
|
||||
adminSettingsService.deleteAdminSettingsByKey(tenantId, settingsKey);
|
||||
attributesService.removeAll(tenantId, tenantId, DataConstants.SERVER_SCOPE, Collections.singletonList(OAUTH2_CLIENT_REGISTRATIONS_PARAMS));
|
||||
clientsParams.remove(tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOAuth2ClientRegistrationAllowed(TenantId tenantId) {
|
||||
@ -351,9 +385,17 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
private OAuth2ClientsParams getMergedOAuth2ClientsParams(String domainName) {
|
||||
private OAuth2ClientsDomainParams getMergedOAuth2ClientsParams(String domainName) {
|
||||
AdminSettings oauth2ClientsSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, constructAdminSettingsDomainKey(domainName));
|
||||
OAuth2ClientsParams result;
|
||||
OAuth2ClientsDomainParams result;
|
||||
|
||||
OAuth2ClientsParams systemOAuth2ClientsParams = getSystemOAuth2ClientsParams(TenantId.SYS_TENANT_ID);
|
||||
OAuth2ClientsDomainParams systemOAuth2ClientsDomainParams = systemOAuth2ClientsParams != null ?
|
||||
systemOAuth2ClientsParams.getClientsDomainsParams().stream()
|
||||
.filter(oAuth2ClientsDomainParams -> domainName.equals(oAuth2ClientsDomainParams.getDomainName()))
|
||||
.findFirst()
|
||||
.orElse(null)
|
||||
: null;
|
||||
if (oauth2ClientsSettings != null) {
|
||||
String strEntityType = oauth2ClientsSettings.getJsonValue().get("entityType").asText();
|
||||
String strEntityId = oauth2ClientsSettings.getJsonValue().get("entityId").asText();
|
||||
@ -363,17 +405,16 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
throw new IllegalStateException("Only tenant can configure OAuth2 for certain domain!");
|
||||
}
|
||||
TenantId tenantId = (TenantId) entityId;
|
||||
result = getTenantOAuth2ClientsParams(tenantId);
|
||||
OAuth2ClientsParams systemOAuth2ClientsParams = getSystemOAuth2ClientsParams(TenantId.SYS_TENANT_ID);
|
||||
if (systemOAuth2ClientsParams != null) {
|
||||
result = getTenantOAuth2ClientsParams(tenantId).getClientsDomainsParams().get(0);
|
||||
if (systemOAuth2ClientsDomainParams != null) {
|
||||
ArrayList<OAuth2ClientRegistration> tenantClientRegistrations = new ArrayList<>(result.getClientRegistrations());
|
||||
tenantClientRegistrations.addAll(systemOAuth2ClientsParams.getClientRegistrations());
|
||||
tenantClientRegistrations.addAll(systemOAuth2ClientsDomainParams.getClientRegistrations());
|
||||
result = result.toBuilder()
|
||||
.clientRegistrations(tenantClientRegistrations)
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
result = getSystemOAuth2ClientsParams(TenantId.SYS_TENANT_ID);
|
||||
result = systemOAuth2ClientsDomainParams;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -423,6 +464,11 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
return client;
|
||||
}
|
||||
|
||||
private Stream<OAuth2ClientRegistration> toClientRegistrationStream(OAuth2ClientsParams oAuth2ClientsParams) {
|
||||
return oAuth2ClientsParams.getClientsDomainsParams().stream()
|
||||
.flatMap(oAuth2ClientsDomainParams -> oAuth2ClientsDomainParams.getClientRegistrations().stream());
|
||||
}
|
||||
|
||||
private final Consumer<OAuth2ClientRegistration> validator = clientRegistration -> {
|
||||
if (StringUtils.isEmpty(clientRegistration.getRegistrationId())) {
|
||||
throw new DataValidationException("Registration ID should be specified!");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user