Merge pull request #2806 from vzikratyi-tb/oauth2-default-dashboard
Oauth2 default dashboard
This commit is contained in:
commit
78d054797e
@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.security.auth.oauth2;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
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.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
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.Tenant;
|
||||||
import org.thingsboard.server.common.data.User;
|
import org.thingsboard.server.common.data.User;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
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.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.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.Authority;
|
||||||
import org.thingsboard.server.common.data.security.UserCredentials;
|
import org.thingsboard.server.common.data.security.UserCredentials;
|
||||||
import org.thingsboard.server.dao.customer.CustomerService;
|
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.oauth2.OAuth2User;
|
||||||
import org.thingsboard.server.dao.tenant.TenantService;
|
import org.thingsboard.server.dao.tenant.TenantService;
|
||||||
import org.thingsboard.server.dao.user.UserService;
|
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.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public abstract class AbstractOAuth2ClientMapper {
|
public abstract class AbstractOAuth2ClientMapper {
|
||||||
|
private static final int DASHBOARDS_REQUEST_LIMIT = 10;
|
||||||
|
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
@ -58,6 +72,9 @@ public abstract class AbstractOAuth2ClientMapper {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CustomerService customerService;
|
private CustomerService customerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DashboardService dashboardService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InstallScripts installScripts;
|
private InstallScripts installScripts;
|
||||||
|
|
||||||
@ -92,6 +109,20 @@ public abstract class AbstractOAuth2ClientMapper {
|
|||||||
user.setEmail(oauth2User.getEmail());
|
user.setEmail(oauth2User.getEmail());
|
||||||
user.setFirstName(oauth2User.getFirstName());
|
user.setFirstName(oauth2User.getFirstName());
|
||||||
user.setLastName(oauth2User.getLastName());
|
user.setLastName(oauth2User.getLastName());
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(oauth2User.getDefaultDashboardName())) {
|
||||||
|
Optional<DashboardId> 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);
|
user = userService.saveUser(user);
|
||||||
if (activateUser) {
|
if (activateUser) {
|
||||||
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId());
|
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId());
|
||||||
@ -143,4 +174,32 @@ public abstract class AbstractOAuth2ClientMapper {
|
|||||||
return customerService.saveCustomer(customer).getId();
|
return customerService.saveCustomer(customer).getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<DashboardId> getDashboardId(TenantId tenantId, String dashboardName) {
|
||||||
|
TextPageLink searchTextLink = new TextPageLink(1, dashboardName);
|
||||||
|
TextPageData<DashboardInfo> dashboardsPage = dashboardService.findDashboardsByTenantId(tenantId, searchTextLink);
|
||||||
|
return dashboardsPage.getData().stream()
|
||||||
|
.findAny()
|
||||||
|
.map(IdBased::getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<DashboardId> getDashboardId(TenantId tenantId, CustomerId customerId, String dashboardName) {
|
||||||
|
TimePageData<DashboardInfo> 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<DashboardInfo> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,10 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen
|
|||||||
String customerName = sub.replace(config.getBasic().getCustomerNamePattern());
|
String customerName = sub.replace(config.getBasic().getCustomerNamePattern());
|
||||||
oauth2User.setCustomerName(customerName);
|
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());
|
return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.isAllowUserCreation(), config.isActivateUser());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,6 +148,10 @@ security:
|
|||||||
# If this field is not empty, user will be created as a user under defined Customer
|
# 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
|
# %{attribute_key} as placeholder for attribute value of attributes of external user object
|
||||||
customerNamePattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_CUSTOMER_NAME_PATTERN:}"
|
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:
|
custom:
|
||||||
url: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_URL:}"
|
url: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_URL:}"
|
||||||
username: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_USERNAME:}"
|
username: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_USERNAME:}"
|
||||||
|
|||||||
@ -28,4 +28,6 @@ public class OAuth2User {
|
|||||||
private String email;
|
private String email;
|
||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
private boolean alwaysFullScreen;
|
||||||
|
private String defaultDashboardName;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,8 @@ public class OAuth2ClientMapperConfig {
|
|||||||
private String tenantNameStrategy;
|
private String tenantNameStrategy;
|
||||||
private String tenantNamePattern;
|
private String tenantNamePattern;
|
||||||
private String customerNamePattern;
|
private String customerNamePattern;
|
||||||
|
private boolean alwaysFullScreen;
|
||||||
|
private String defaultDashboardName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user