diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java index dd49418204..c51af005cc 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java @@ -15,6 +15,9 @@ */ package org.thingsboard.server.service.security.auth.oauth2; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Strings; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -22,14 +25,21 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.IdBased; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.user.UserService; @@ -40,11 +50,15 @@ import org.thingsboard.server.service.security.model.UserPrincipal; import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @Slf4j public abstract class AbstractOAuth2ClientMapper { + private static final int DASHBOARDS_REQUEST_LIMIT = 10; + + private static final ObjectMapper objectMapper = new ObjectMapper(); @Autowired private UserService userService; @@ -58,6 +72,9 @@ public abstract class AbstractOAuth2ClientMapper { @Autowired private CustomerService customerService; + @Autowired + private DashboardService dashboardService; + @Autowired private InstallScripts installScripts; @@ -92,6 +109,20 @@ public abstract class AbstractOAuth2ClientMapper { user.setEmail(oauth2User.getEmail()); user.setFirstName(oauth2User.getFirstName()); user.setLastName(oauth2User.getLastName()); + + if (!StringUtils.isEmpty(oauth2User.getDefaultDashboardName())) { + Optional dashboardIdOpt = + user.getAuthority() == Authority.TENANT_ADMIN ? + getDashboardId(tenantId, oauth2User.getDefaultDashboardName()) + : getDashboardId(tenantId, customerId, oauth2User.getDefaultDashboardName()); + if (dashboardIdOpt.isPresent()) { + ObjectNode additionalInfo = objectMapper.createObjectNode(); + additionalInfo.put("defaultDashboardFullscreen", oauth2User.isAlwaysFullScreen()); + additionalInfo.put("defaultDashboardId", dashboardIdOpt.get().getId().toString()); + user.setAdditionalInfo(additionalInfo); + } + } + user = userService.saveUser(user); if (activateUser) { UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); @@ -143,4 +174,32 @@ public abstract class AbstractOAuth2ClientMapper { return customerService.saveCustomer(customer).getId(); } } + + private Optional getDashboardId(TenantId tenantId, String dashboardName) { + TextPageLink searchTextLink = new TextPageLink(1, dashboardName); + TextPageData dashboardsPage = dashboardService.findDashboardsByTenantId(tenantId, searchTextLink); + return dashboardsPage.getData().stream() + .findAny() + .map(IdBased::getId); + } + + private Optional getDashboardId(TenantId tenantId, CustomerId customerId, String dashboardName) { + TimePageData dashboardsPage = null; + do { + TimePageLink timePageLink = dashboardsPage != null ? + dashboardsPage.getNextPageLink() : new TimePageLink(DASHBOARDS_REQUEST_LIMIT); + try { + dashboardsPage = dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, timePageLink).get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException("Failed to get customer's dashboards.", e); + } + Optional dashboardInfoOpt = dashboardsPage.getData().stream() + .filter(dashboardInfo -> dashboardName.equals(dashboardInfo.getName())) + .findAny(); + if (dashboardInfoOpt.isPresent()) { + return dashboardInfoOpt.map(DashboardInfo::getId); + } + } while (dashboardsPage.hasNext()); + return Optional.empty(); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java index c6b6aeaae3..2170479f92 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java @@ -56,6 +56,10 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen String customerName = sub.replace(config.getBasic().getCustomerNamePattern()); oauth2User.setCustomerName(customerName); } + oauth2User.setAlwaysFullScreen(config.getBasic().isAlwaysFullScreen()); + if (!StringUtils.isEmpty(config.getBasic().getDefaultDashboardName())) { + oauth2User.setDefaultDashboardName(config.getBasic().getDefaultDashboardName()); + } return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.isAllowUserCreation(), config.isActivateUser()); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 436f3c8410..4fe337bd86 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -148,6 +148,10 @@ security: # If this field is not empty, user will be created as a user under defined Customer # %{attribute_key} as placeholder for attribute value of attributes of external user object customerNamePattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_CUSTOMER_NAME_PATTERN:}" + # If this field is not empty, user will be created with default defined Dashboard + defaultDashboardName: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_DEFAULT_DASHBOARD_NAME:}" + # If this field is set 'true' along with non-empty 'defaultDashboardName', user will start from the defined Dashboard in fullscreen mode + alwaysFullScreen: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_ALWAYS_FULL_SCREEN:false}" custom: url: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_URL:}" username: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_USERNAME:}" diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java index c0075633e5..7ebc79cff2 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java @@ -28,4 +28,6 @@ public class OAuth2User { private String email; private String firstName; private String lastName; + private boolean alwaysFullScreen; + private String defaultDashboardName; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java index 47f3746980..f2f23843f2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java @@ -34,6 +34,8 @@ public class OAuth2ClientMapperConfig { private String tenantNameStrategy; private String tenantNamePattern; private String customerNamePattern; + private boolean alwaysFullScreen; + private String defaultDashboardName; } @Data