added test for Oauth2Controller, DomainController, MobileAppController

This commit is contained in:
dashevchenko 2024-07-19 17:16:41 +03:00
parent 1429d6a97c
commit b57744f5d5
30 changed files with 757 additions and 223 deletions

View File

@ -167,6 +167,9 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -897,4 +900,15 @@ public abstract class BaseController {
}
}
protected List<OAuth2ClientId> getOAuth2ClientIds(UUID[] ids) throws ThingsboardException {
List<UUID> oauth2ClientIds = ids != null ? Arrays.asList(ids) : Collections.emptyList();
List<OAuth2ClientId> oAuth2ClientIds = new ArrayList<>();
for (UUID id : oauth2ClientIds) {
OAuth2ClientId oauth2ClientId = new OAuth2ClientId(id);
checkOauth2ClientId(oauth2ClientId, Operation.READ);
oAuth2ClientIds.add(oauth2ClientId);
}
return oAuth2ClientIds;
}
}

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
@ -25,11 +26,11 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.domain.DomainInfo;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -41,9 +42,6 @@ import org.thingsboard.server.service.entitiy.domain.TbDomainService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@ -70,53 +68,30 @@ public class DomainController extends BaseController {
@PostMapping(value = "/domain")
public Domain saveDomain(
@Parameter(description = "A JSON value representing the Domain.", required = true)
@RequestBody Domain domain,
@RequestBody @Valid Domain domain,
@Parameter(description = "A list of oauth2 client registration ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam(name = "oauth2ClientRegistrationIds", required = false) String[] ids) throws Exception {
List<String> oauth2ClientIds = ids != null ? Arrays.asList(ids) : Collections.emptyList();
@RequestParam(name = "oauth2ClientIds", required = false) UUID[] ids) throws Exception {
domain.setTenantId(getCurrentUser().getTenantId());
checkEntity(domain.getId(), domain, Resource.DOMAIN);
List<OAuth2ClientId> oAuth2ClientIds = new ArrayList<>();
for (String id : oauth2ClientIds) {
OAuth2ClientId oauth2ClientId = new OAuth2ClientId(toUUID(id));
checkOauth2ClientId(oauth2ClientId, Operation.READ);
oAuth2ClientIds.add(oauth2ClientId);
}
return tbDomainService.save(domain, oAuth2ClientIds, getCurrentUser());
return tbDomainService.save(domain, getOAuth2ClientIds(ids), getCurrentUser());
}
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)",
notes = "Update oauth2 clients for the specified domain. ")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@PostMapping(value = "/domain/{id}/oauth2Clients")
@PutMapping(value = "/domain/{id}/oauth2Clients")
public void updateOauth2Clients(@PathVariable UUID id,
@RequestBody UUID[] oauth2ClientIds) throws ThingsboardException {
@RequestBody UUID[] clientIds) throws ThingsboardException {
DomainId domainId = new DomainId(id);
Domain domain = null;
try {
domain = checkDomainId(domainId, Operation.WRITE);
List<OAuth2ClientId> oAuth2ClientIds = new ArrayList<>();
for (UUID outh2CLientId : oauth2ClientIds) {
OAuth2ClientId oAuth2ClientId = new OAuth2ClientId(outh2CLientId);
checkEntityId(oAuth2ClientId, Operation.READ);
oAuth2ClientIds.add(oAuth2ClientId);
}
domainService.updateOauth2Clients(getTenantId(), domainId, oAuth2ClientIds);
logEntityActionService.logEntityAction(domain.getTenantId(), domain.getId(), domain,
ActionType.UPDATED, getCurrentUser(), oAuth2ClientIds.toString());
} catch (Exception e) {
if (domain != null) {
logEntityActionService.logEntityAction(getTenantId(), domainId, domain,
ActionType.UPDATED, getCurrentUser(), e);
}
throw e;
}
Domain domain = checkDomainId(domainId, Operation.WRITE);
List<OAuth2ClientId> oAuth2ClientIds = getOAuth2ClientIds(clientIds);
tbDomainService.updateOauth2Clients(domain, oAuth2ClientIds, getCurrentUser());
}
@ApiOperation(value = "Get Domain infos (getDomainInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH)
@ApiOperation(value = "Get Domain infos (getTenantDomainInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@GetMapping(value = "/domain/infos")
public List<DomainInfo> getDomainInfos() throws ThingsboardException {
public List<DomainInfo> getTenantDomainInfos() throws ThingsboardException {
return domainService.findDomainInfosByTenantId(getTenantId());
}

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
@ -25,11 +26,11 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.MobileAppId;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
@ -40,8 +41,8 @@ import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.mobile.TbMobileAppService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -61,57 +62,37 @@ public class MobileAppController extends BaseController {
@ApiOperation(value = "Save Or update Mobile app (saveMobileApp)",
notes = "Create or update the Mobile app. When creating mobile app, platform generates Mobile App Id as " + UUID_WIKI_LINK +
"The newly created Mobile App Id will be present in the response. " +
"Specify existing Mobile App Id to update the domain. " +
"Specify existing Mobile App Id to update the mobile app. " +
"Referencing non-existing Mobile App Id will cause 'Not Found' error." +
"\n\nMobile app package name is unique for entire platform setup.\n\n")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@PostMapping(value = "/mobileApp")
public MobileApp saveMobileApp(
@Parameter(description = "A JSON value representing the Domain.", required = true)
@RequestBody MobileApp mobileApp,
@Parameter(description = "A JSON value representing the Mobile Application.", required = true)
@RequestBody @Valid MobileApp mobileApp,
@Parameter(description = "A list of entity group ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam(name = "oauth2ClientIds", required = false) UUID[] oauth2ClientIds) throws Exception {
@RequestParam(name = "oauth2ClientIds", required = false) UUID[] ids) throws Exception {
mobileApp.setTenantId(getCurrentUser().getTenantId());
List<OAuth2ClientId> oAuth2Clients = new ArrayList<>();
for (UUID id : oauth2ClientIds) {
OAuth2ClientId oauth2ClientId = new OAuth2ClientId(id);
checkOauth2ClientId(oauth2ClientId, Operation.READ);
oAuth2Clients.add(oauth2ClientId);
}
return tbMobileAppService.save(mobileApp, oAuth2Clients, getCurrentUser());
checkEntity(mobileApp.getId(), mobileApp, Resource.MOBILE_APP);
return tbMobileAppService.save(mobileApp, getOAuth2ClientIds(ids), getCurrentUser());
}
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)",
notes = "Update oauth2 clients to the specified mobile app. ")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@PostMapping(value = "/mobileApp/{id}/oauth2Clients")
@PutMapping(value = "/mobileApp/{id}/oauth2Clients")
public void updateOauth2Clients(@PathVariable UUID id,
@RequestBody UUID[] oauth2ClientIds) throws ThingsboardException {
@RequestBody UUID[] clientIds) throws ThingsboardException {
MobileAppId mobileAppId = new MobileAppId(id);
MobileApp mobileApp = null;
try {
mobileApp = checkMobileAppId(mobileAppId, Operation.WRITE);
List<OAuth2ClientId> oAuth2ClientIds = new ArrayList<>();
for (UUID outh2CLientId : oauth2ClientIds) {
OAuth2ClientId oAuth2ClientId = new OAuth2ClientId(outh2CLientId);
checkEntityId(oAuth2ClientId, Operation.READ);
oAuth2ClientIds.add(oAuth2ClientId);
}
mobileAppService.updateOauth2Clients(getTenantId(), mobileAppId, oAuth2ClientIds);
} catch (Exception e) {
if (mobileApp != null) {
logEntityActionService.logEntityAction(getTenantId(), mobileAppId, mobileApp,
ActionType.UPDATED, getCurrentUser(), e);
}
throw e;
}
MobileApp mobileApp = checkMobileAppId(mobileAppId, Operation.WRITE);
List<OAuth2ClientId> oAuth2ClientIds = getOAuth2ClientIds(clientIds);
tbMobileAppService.updateOauth2Clients(mobileApp, oAuth2ClientIds, getCurrentUser());
}
@ApiOperation(value = "Get mobile app infos (getMobileAppInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH)
@ApiOperation(value = "Get mobile app infos (getTenantMobileAppInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@GetMapping(value = "/mobileApp/infos")
public List<MobileAppInfo> getMobileAppInfos() throws ThingsboardException {
public List<MobileAppInfo> getTenantMobileAppInfos() throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
return mobileAppService.findMobileAppInfosByTenantId(tenantId);
}

View File

@ -18,26 +18,25 @@ package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.oauth2.OAuth2Configuration;
@ -69,16 +68,16 @@ public class OAuth2Controller extends BaseController {
@ApiOperation(value = "Get OAuth2 clients (getOAuth2Clients)", notes = "Get the list of OAuth2 clients " +
"to log in with, available for such domain scheme (HTTP or HTTPS) (if x-forwarded-proto request header is present - " +
"the scheme is known from it) and domain name and port (port may be known from x-forwarded-port header)")
@PostMapping(value = "/noauth/oauth2Clients")
@PostMapping(value = "/noauth/oauth2/client")
public List<OAuth2ClientLoginInfo> getOAuth2Clients(HttpServletRequest request,
@Parameter(description = "Mobile application package name, to find OAuth2 clients " +
"where there is configured mobile application with such package name")
@RequestParam(required = false) String pkgName,
"where there is configured mobile application with such package name")
@RequestParam(required = false) String pkgName,
@Parameter(description = "Platform type to search OAuth2 clients for which " +
"the usage with this platform type is allowed in the settings. " +
"If platform type is not one of allowable values - it will just be ignored",
schema = @Schema(allowableValues = {"WEB", "ANDROID", "IOS"}))
@RequestParam(required = false) String platform) throws ThingsboardException {
"the usage with this platform type is allowed in the settings. " +
"If platform type is not one of allowable values - it will just be ignored",
schema = @Schema(allowableValues = {"WEB", "ANDROID", "IOS"}))
@RequestParam(required = false) String platform) throws ThingsboardException {
if (log.isDebugEnabled()) {
log.debug("Executing getOAuth2Clients: [{}][{}][{}]", request.getScheme(), request.getServerName(), request.getServerPort());
Enumeration<String> headerNames = request.getHeaderNames();
@ -104,7 +103,7 @@ public class OAuth2Controller extends BaseController {
@ApiOperation(value = "Save OAuth2 Client Registration (saveOAuth2Client)", notes = SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@PostMapping(value = "/oauth2/client")
public OAuth2Client saveOAuth2Client(@RequestBody OAuth2Client oAuth2Client) throws Exception {
public OAuth2Client saveOAuth2Client(@RequestBody @Valid OAuth2Client oAuth2Client) throws Exception {
TenantId tenantId = getTenantId();
oAuth2Client.setTenantId(tenantId);
checkEntity(oAuth2Client.getId(), oAuth2Client, Resource.OAUTH2_CLIENT);
@ -129,8 +128,7 @@ public class OAuth2Controller extends BaseController {
@ApiOperation(value = "Delete oauth2 client (deleteAsset)",
notes = "Deletes the asset and all the relations (from and to the asset). Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/oauth2/client/{id}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
@DeleteMapping(value = "/oauth2/client/{id}")
public void deleteOauth2Client(@PathVariable UUID id) throws Exception {
OAuth2ClientId oAuth2ClientId = new OAuth2ClientId(id);
OAuth2Client oAuth2Client = checkOauth2ClientId(oAuth2ClientId, Operation.DELETE);
@ -142,7 +140,7 @@ public class OAuth2Controller extends BaseController {
"further log in processing. This URL may be configured as 'security.oauth2.loginProcessingUrl' property in yml configuration file, or " +
"as 'SECURITY_OAUTH2_LOGIN_PROCESSING_URL' env variable. By default it is '/login/oauth2/code/'" + SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@RequestMapping(value = "/oauth2/loginProcessingUrl", method = RequestMethod.GET)
@GetMapping(value = "/oauth2/loginProcessingUrl")
public String getLoginProcessingUrl() {
return "\"" + oAuth2Configuration.getLoginProcessingUrl() + "\"";
}

View File

@ -30,7 +30,6 @@ import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;

View File

@ -43,13 +43,27 @@ public class DefaultTbDomainService extends AbstractTbEntityService implements T
TenantId tenantId = domain.getTenantId();
try {
Domain savedDomain = checkNotNull(domainService.saveDomain(tenantId, domain));
logEntityActionService.logEntityAction(tenantId, savedDomain.getId(), domain, actionType, user);
if (!CollectionUtils.isEmpty(oAuth2Clients)) {
domainService.updateOauth2Clients(domain.getTenantId(), savedDomain.getId(), oAuth2Clients);
}
logEntityActionService.logEntityAction(tenantId, savedDomain.getId(), domain, actionType, user, oAuth2Clients);
return savedDomain;
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), domain, actionType, user, e);
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), domain, actionType, user, e, oAuth2Clients);
throw e;
}
}
@Override
public void updateOauth2Clients(Domain domain, List<OAuth2ClientId> oAuth2ClientIds, User user) {
ActionType actionType = ActionType.UPDATED;
TenantId tenantId = domain.getTenantId();
DomainId domainId = domain.getId();
try {
domainService.updateOauth2Clients(tenantId, domainId, oAuth2ClientIds);
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, oAuth2ClientIds.toString());
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, e, oAuth2ClientIds.toString());
throw e;
}
}
@ -62,10 +76,9 @@ public class DefaultTbDomainService extends AbstractTbEntityService implements T
DomainId domainId = domain.getId();
try {
domainService.deleteDomainById(tenantId, domainId);
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, domain.getName());
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user);
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), actionType, user, e,
domainId.toString());
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, e);
throw e;
}
}

View File

@ -25,6 +25,8 @@ public interface TbDomainService {
Domain save(Domain domain, List<OAuth2ClientId> oAuth2Clients, User user) throws Exception;
void updateOauth2Clients(Domain domain, List<OAuth2ClientId> oAuth2ClientIds, User user);
void delete(Domain domain, User user);
}

View File

@ -43,10 +43,10 @@ public class DefaultTbMobileAppService extends AbstractTbEntityService implement
TenantId tenantId = mobileApp.getTenantId();
try {
MobileApp savedMobileApp = checkNotNull(mobileAppService.saveMobileApp(tenantId, mobileApp));
logEntityActionService.logEntityAction(tenantId, savedMobileApp.getId(), mobileApp, actionType, user);
if (!CollectionUtils.isEmpty(oauth2Clients)) {
mobileAppService.updateOauth2Clients(tenantId, savedMobileApp.getId(), oauth2Clients);
}
logEntityActionService.logEntityAction(tenantId, savedMobileApp.getId(), mobileApp, actionType, user);
return savedMobileApp;
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.MOBILE_APP), mobileApp, actionType, user, e);
@ -54,6 +54,20 @@ public class DefaultTbMobileAppService extends AbstractTbEntityService implement
}
}
@Override
public void updateOauth2Clients(MobileApp mobileApp, List<OAuth2ClientId> oAuth2ClientIds, User user) {
ActionType actionType = ActionType.UPDATED;
TenantId tenantId = mobileApp.getTenantId();
MobileAppId mobileAppId = mobileApp.getId();
try {
mobileAppService.updateOauth2Clients(tenantId, mobileAppId, oAuth2ClientIds);
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, oAuth2ClientIds.toString());
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, e, oAuth2ClientIds.toString());
throw e;
}
}
@Override
@Transactional
public void delete(MobileApp mobileApp, User user) {
@ -62,10 +76,9 @@ public class DefaultTbMobileAppService extends AbstractTbEntityService implement
MobileAppId mobileAppId = mobileApp.getId();
try {
mobileAppService.deleteMobileAppById(tenantId, mobileAppId);
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, mobileApp.getPkgName());
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user);
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.MOBILE_APP), actionType, user, e,
mobileAppId.toString());
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, e);
throw e;
}
}

View File

@ -25,6 +25,8 @@ public interface TbMobileAppService {
MobileApp save(MobileApp mobileApp, List<OAuth2ClientId> oauth2Clients, User user) throws Exception;
void updateOauth2Clients(MobileApp mobileApp, List<OAuth2ClientId> oAuth2ClientIds, User user);
void delete(MobileApp mobileApp, User user);
}

View File

@ -53,10 +53,9 @@ public class DefaultTbOauth2ClientService extends AbstractTbEntityService implem
OAuth2ClientId oAuth2ClientId = oAuth2Client.getId();
try {
oAuth2ClientService.deleteOAuth2ClientById(tenantId, oAuth2ClientId);
logEntityActionService.logEntityAction(tenantId, oAuth2ClientId, oAuth2Client, actionType, user, oAuth2Client.getName());
logEntityActionService.logEntityAction(tenantId, oAuth2ClientId, oAuth2Client, actionType, user);
} catch (Exception e) {
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OAUTH2_CLIENT), actionType, user, e,
oAuth2ClientId.toString());
logEntityActionService.logEntityAction(tenantId, oAuth2ClientId, oAuth2Client, actionType, user, e);
throw e;
}
}

View File

@ -0,0 +1,178 @@
/**
* Copyright © 2016-2024 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.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.domain.DomainInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.MapperType;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Slf4j
@DaoSqlTest
public class DomainControllerTest extends AbstractControllerTest {
@Before
public void setUp() throws Exception {
loginSysAdmin();
}
@After
public void tearDown() throws Exception {
List<DomainInfo> domains = doGetTyped("/api/domain/infos", new TypeReference<List<DomainInfo>>() {
});
for (Domain domain : domains) {
doDelete("/api/domain/" + domain.getId().getId())
.andExpect(status().isOk());
}
List<OAuth2ClientInfo> oAuth2ClientInfos = doGetTyped("/api/oauth2/client/infos", new TypeReference<List<OAuth2ClientInfo>>() {
});
for (OAuth2ClientInfo oAuth2ClientInfo : oAuth2ClientInfos) {
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString())
.andExpect(status().isOk());
}
}
@Test
public void testSaveDomain() throws Exception {
List<DomainInfo> domainInfos = doGetTyped("/api/domain/infos", new TypeReference<List<DomainInfo>>() {
});
assertThat(domainInfos).isEmpty();
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true);
Domain savedDomain = doPost("/api/domain", domain, Domain.class);
List<DomainInfo> domainInfos2 = doGetTyped("/api/domain/infos", new TypeReference<List<DomainInfo>>() {
});
assertThat(domainInfos2).hasSize(1);
assertThat(domainInfos2.get(0)).isEqualTo(new DomainInfo(savedDomain, Collections.emptyList()));
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId());
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, Collections.emptyList()));
doDelete("/api/domain/" + savedDomain.getId().getId());
doGet("/api/domain/info/{id}", savedDomain.getId().getId())
.andExpect(status().isNotFound());
}
@Test
public void testSaveDomainWithoutName() throws Exception {
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, null, true, true);
doPost("/api/domain", domain)
.andExpect(status().isBadRequest())
.andExpect(statusReason(containsString("name must not be blank")));
}
@Test
public void testUpdateDomainOauth2Clients() throws Exception {
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true);
Domain savedDomain = doPost("/api/domain", domain, Domain.class);
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client");
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class);
OAuth2Client oAuth2Client2 = validClientInfo(TenantId.SYS_TENANT_ID, "test facebook client");
OAuth2Client savedOAuth2Client2 = doPost("/api/oauth2/client", oAuth2Client2, OAuth2Client.class);
doPut("/api/domain/" + savedDomain.getId() + "/oauth2Clients", List.of(savedOAuth2Client.getId().getId(), savedOAuth2Client2.getId().getId()));
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId());
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client),
new OAuth2ClientInfo(savedOAuth2Client2))));
doPut("/api/domain/" + savedDomain.getId() + "/oauth2Clients", List.of(savedOAuth2Client2.getId().getId()));
DomainInfo retrievedDomainInfo2 = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId());
assertThat(retrievedDomainInfo2).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client2))));
}
@Test
public void testCreateDomainWithOauth2Clients() throws Exception {
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client");
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class);
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true);
Domain savedDomain = doPost("/api/domain?oauth2ClientIds=" + savedOAuth2Client.getId().getId(), domain, Domain.class);
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId());
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client))));
}
private Domain constructDomain(TenantId tenantId, String domainName, boolean oauth2Enabled, boolean propagateToEdge) {
Domain domain = new Domain();
domain.setTenantId(tenantId);
domain.setName(domainName);
domain.setOauth2Enabled(oauth2Enabled);
domain.setPropagateToEdge(propagateToEdge);
return domain;
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title) {
return validClientInfo(tenantId, title, null);
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title, List<PlatformType> platforms) {
OAuth2Client oAuth2Client = new OAuth2Client();
oAuth2Client.setTenantId(tenantId);
oAuth2Client.setTitle(title);
oAuth2Client.setClientId(UUID.randomUUID().toString());
oAuth2Client.setClientSecret(UUID.randomUUID().toString());
oAuth2Client.setAuthorizationUri(UUID.randomUUID().toString());
oAuth2Client.setAccessTokenUri(UUID.randomUUID().toString());
oAuth2Client.setScope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setPlatforms(platforms == null ? Collections.emptyList() : platforms);
oAuth2Client.setUserInfoUri(UUID.randomUUID().toString());
oAuth2Client.setUserNameAttributeName(UUID.randomUUID().toString());
oAuth2Client.setJwkSetUri(UUID.randomUUID().toString());
oAuth2Client.setClientAuthenticationMethod(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonLabel(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonIcon(UUID.randomUUID().toString());
oAuth2Client.setAdditionalInfo(JacksonUtil.newObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setMapperConfig(
OAuth2MapperConfig.builder()
.allowUserCreation(true)
.activateUser(true)
.type(MapperType.CUSTOM)
.custom(
OAuth2CustomMapperConfig.builder()
.url(UUID.randomUUID().toString())
.build()
)
.build());
return oAuth2Client;
}
}

View File

@ -0,0 +1,180 @@
/**
* Copyright © 2016-2024 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.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.common.data.mobile.MobileAppInfo;
import org.thingsboard.server.common.data.oauth2.MapperType;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Slf4j
@DaoSqlTest
public class MobileAppControllerTest extends AbstractControllerTest {
@Before
public void setUp() throws Exception {
loginSysAdmin();
}
@After
public void tearDown() throws Exception {
List<MobileAppInfo> mobileAppInfos = doGetTyped("/api/mobileApp/infos", new TypeReference<List<MobileAppInfo>>() {
});
for (MobileApp mobileApp : mobileAppInfos) {
doDelete("/api/mobileApp/" + mobileApp.getId().getId())
.andExpect(status().isOk());
}
List<OAuth2ClientInfo> oAuth2ClientInfos = doGetTyped("/api/oauth2/client/infos", new TypeReference<List<OAuth2ClientInfo>>() {
});
for (OAuth2ClientInfo oAuth2ClientInfo : oAuth2ClientInfos) {
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString())
.andExpect(status().isOk());
}
}
@Test
public void testSaveMobileApp() throws Exception {
List<MobileAppInfo> MobileAppInfos = doGetTyped("/api/mobileApp/infos", new TypeReference<List<MobileAppInfo>>() {
});
assertThat(MobileAppInfos).isEmpty();
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true);
MobileApp savedMobileApp = doPost("/api/mobileApp", mobileApp, MobileApp.class);
List<MobileAppInfo> MobileAppInfos2 = doGetTyped("/api/mobileApp/infos", new TypeReference<List<MobileAppInfo>>() {
});
assertThat(MobileAppInfos2).hasSize(1);
assertThat(MobileAppInfos2.get(0)).isEqualTo(new MobileAppInfo(savedMobileApp, Collections.emptyList()));
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId());
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, Collections.emptyList()));
doDelete("/api/mobileApp/" + savedMobileApp.getId().getId());
doGet("/api/mobileApp/info/{id}", savedMobileApp.getId().getId())
.andExpect(status().isNotFound());
}
@Test
public void testSaveMobileAppWithShortAppSecret() throws Exception {
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "mobileApp.ce", true);
mobileApp.setAppSecret("short");
doPost("/api/mobileApp", mobileApp)
.andExpect(status().isBadRequest())
.andExpect(statusReason(containsString("appSecret must be at least 16 characters")));
}
@Test
public void testUpdateMobileAppOauth2Clients() throws Exception {
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true);
MobileApp savedMobileApp = doPost("/api/mobileApp", mobileApp, MobileApp.class);
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client");
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class);
OAuth2Client oAuth2Client2 = validClientInfo(TenantId.SYS_TENANT_ID, "test facebook client");
OAuth2Client savedOAuth2Client2 = doPost("/api/oauth2/client", oAuth2Client2, OAuth2Client.class);
doPut("/api/mobileApp/" + savedMobileApp.getId() + "/oauth2Clients", List.of(savedOAuth2Client.getId().getId(), savedOAuth2Client2.getId().getId()));
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId());
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client),
new OAuth2ClientInfo(savedOAuth2Client2))));
doPut("/api/mobileApp/" + savedMobileApp.getId() + "/oauth2Clients", List.of(savedOAuth2Client2.getId().getId()));
MobileAppInfo retrievedMobileAppInfo2 = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId());
assertThat(retrievedMobileAppInfo2).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client2))));
}
@Test
public void testCreateMobileAppWithOauth2Clients() throws Exception {
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client");
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class);
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true);
MobileApp savedMobileApp = doPost("/api/mobileApp?oauth2ClientIds=" + savedOAuth2Client.getId().getId(), mobileApp, MobileApp.class);
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId());
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client))));
}
private MobileApp validMobileApp(TenantId tenantId, String mobileAppName, boolean oauth2Enabled) {
MobileApp MobileApp = new MobileApp();
MobileApp.setTenantId(tenantId);
MobileApp.setPkgName(mobileAppName);
MobileApp.setAppSecret(StringUtils.randomAlphanumeric(24));
MobileApp.setOauth2Enabled(oauth2Enabled);
return MobileApp;
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title) {
return validClientInfo(tenantId, title, null);
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title, List<PlatformType> platforms) {
OAuth2Client oAuth2Client = new OAuth2Client();
oAuth2Client.setTenantId(tenantId);
oAuth2Client.setTitle(title);
oAuth2Client.setClientId(UUID.randomUUID().toString());
oAuth2Client.setClientSecret(UUID.randomUUID().toString());
oAuth2Client.setAuthorizationUri(UUID.randomUUID().toString());
oAuth2Client.setAccessTokenUri(UUID.randomUUID().toString());
oAuth2Client.setScope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setPlatforms(platforms == null ? Collections.emptyList() : platforms);
oAuth2Client.setUserInfoUri(UUID.randomUUID().toString());
oAuth2Client.setUserNameAttributeName(UUID.randomUUID().toString());
oAuth2Client.setJwkSetUri(UUID.randomUUID().toString());
oAuth2Client.setClientAuthenticationMethod(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonLabel(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonIcon(UUID.randomUUID().toString());
oAuth2Client.setAdditionalInfo(JacksonUtil.newObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setMapperConfig(
OAuth2MapperConfig.builder()
.allowUserCreation(true)
.activateUser(true)
.type(MapperType.CUSTOM)
.custom(
OAuth2CustomMapperConfig.builder()
.url(UUID.randomUUID().toString())
.build()
)
.build());
return oAuth2Client;
}
}

View File

@ -0,0 +1,118 @@
/**
* Copyright © 2016-2024 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.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.MapperType;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Slf4j
@DaoSqlTest
public class Oauth2ClientControllerTest extends AbstractControllerTest {
@Before
public void setUp() throws Exception {
loginSysAdmin();
}
@After
public void tearDown() throws Exception {
List<OAuth2ClientInfo> oAuth2ClientInfos = doGetTyped("/api/oauth2/client/infos", new TypeReference<List<OAuth2ClientInfo>>() {
});
for (OAuth2ClientInfo oAuth2ClientInfo : oAuth2ClientInfos) {
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString())
.andExpect(status().isOk());
}
}
@Test
public void testSaveOauth2Client() throws Exception {
loginSysAdmin();
List<OAuth2ClientInfo> oAuth2ClientInfos = doGetTyped("/api/oauth2/client/infos", new TypeReference<List<OAuth2ClientInfo>>() {
});
assertThat(oAuth2ClientInfos).isEmpty();
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client");
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class);
List<OAuth2ClientInfo> oAuth2ClientInfos2 = doGetTyped("/api/oauth2/client/infos", new TypeReference<List<OAuth2ClientInfo>>() {
});
assertThat(oAuth2ClientInfos2).hasSize(1);
assertThat(oAuth2ClientInfos2.get(0)).isEqualTo(new OAuth2ClientInfo(savedOAuth2Client));
OAuth2Client retrievedOAuth2ClientInfo = doGet("/api/oauth2/client/{id}", OAuth2Client.class, savedOAuth2Client.getId().getId());
assertThat(retrievedOAuth2ClientInfo).isEqualTo(savedOAuth2Client);
doDelete("/api/oauth2/client/" + savedOAuth2Client.getId().getId());
doGet("/api/oauth2/client/{id}", savedOAuth2Client.getId().getId())
.andExpect(status().isNotFound());
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title) {
return validClientInfo(tenantId, title, null);
}
protected OAuth2Client validClientInfo(TenantId tenantId, String title, List<PlatformType> platforms) {
OAuth2Client oAuth2Client = new OAuth2Client();
oAuth2Client.setTenantId(tenantId);
oAuth2Client.setTitle(title);
oAuth2Client.setClientId(UUID.randomUUID().toString());
oAuth2Client.setClientSecret(UUID.randomUUID().toString());
oAuth2Client.setAuthorizationUri(UUID.randomUUID().toString());
oAuth2Client.setAccessTokenUri(UUID.randomUUID().toString());
oAuth2Client.setScope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setPlatforms(platforms == null ? Collections.emptyList() : platforms);
oAuth2Client.setUserInfoUri(UUID.randomUUID().toString());
oAuth2Client.setUserNameAttributeName(UUID.randomUUID().toString());
oAuth2Client.setJwkSetUri(UUID.randomUUID().toString());
oAuth2Client.setClientAuthenticationMethod(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonLabel(UUID.randomUUID().toString());
oAuth2Client.setLoginButtonIcon(UUID.randomUUID().toString());
oAuth2Client.setAdditionalInfo(JacksonUtil.newObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
oAuth2Client.setMapperConfig(
OAuth2MapperConfig.builder()
.allowUserCreation(true)
.activateUser(true)
.type(MapperType.CUSTOM)
.custom(
OAuth2CustomMapperConfig.builder()
.url(UUID.randomUUID().toString())
.build()
)
.build());
return oAuth2Client;
}
}

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.common.data.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ -35,6 +36,7 @@ public class Domain extends BaseData<DomainId> implements HasTenantId, HasName {
@Schema(description = "JSON object with Tenant Id")
private TenantId tenantId;
@Schema(description = "Domain name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
private String name;
@Schema(description = "Whether OAuth2 settings are enabled or not")
private boolean oauth2Enabled;

View File

@ -16,8 +16,10 @@
package org.thingsboard.server.common.data.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.oauth2.HasOauth2Clients;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
@ -25,6 +27,8 @@ import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema
public class DomainInfo extends Domain implements HasOauth2Clients {

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.mobile;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.MobileAppId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.validation.Length;
@EqualsAndHashCode(callSuper = true)
@Data
@ -36,8 +38,11 @@ public class MobileApp extends BaseData<MobileAppId> implements HasTenantId, Has
@Schema(description = "JSON object with Tenant Id")
private TenantId tenantId;
@Schema(description = "Application package name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty
private String pkgName;
@Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty
@Length(min = 16, message = "must be at least 16 characters")
private String appSecret;
@Schema(description = "Whether OAuth2 settings are enabled or not")
private boolean oauth2Enabled;

View File

@ -32,6 +32,8 @@ public @interface Length {
int max() default 255;
int min() default 0;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};

View File

@ -30,13 +30,12 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.oauth2.OAuth2ClientDao;
import org.thingsboard.server.dao.oauth2.OAuth2Utils;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.Validator;
import java.util.ArrayList;
@ -58,13 +57,10 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe
private OAuth2ClientDao oauth2ClientDao;
@Autowired
private DomainDao domainDao;
@Autowired
private DataValidator<Domain> domainValidator;
@Override
public Domain saveDomain(TenantId tenantId, Domain domain) {
log.trace("Executing saveDomain [{}]", domain);
domainValidator.validate(domain, Domain::getTenantId);
try {
Domain savedDomain = domainDao.save(tenantId, domain);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedDomain).build());
@ -109,7 +105,7 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe
@Override
public void deleteDomainById(TenantId tenantId, DomainId domainId) {
log.trace("Executing deleteDomain [{}]", domainId.getId());
log.trace("Executing deleteDomainById [{}]", domainId.getId());
domainDao.removeById(tenantId, domainId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(domainId).build());
}
@ -127,7 +123,7 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe
List<DomainInfo> domainInfos = new ArrayList<>();
domains.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(domain -> {
domainInfos.add(new DomainInfo(domain, oauth2ClientDao.findByDomainId(domain.getUuidId()).stream()
.map(OAuth2Utils::toClientInfo)
.map(OAuth2ClientInfo::new)
.collect(Collectors.toList())));
});
return domainInfos;
@ -141,7 +137,7 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe
return null;
}
return new DomainInfo(domain, oauth2ClientDao.findByDomainId(domain.getUuidId()).stream()
.map(OAuth2Utils::toClientInfo)
.map(OAuth2ClientInfo::new)
.collect(Collectors.toList()));
}

View File

@ -30,13 +30,12 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.common.data.mobile.MobileAppInfo;
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.oauth2.OAuth2ClientDao;
import org.thingsboard.server.dao.oauth2.OAuth2Utils;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.Validator;
import java.util.ArrayList;
@ -58,13 +57,10 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil
private OAuth2ClientDao oauth2ClientDao;
@Autowired
private MobileAppDao mobileAppDao;
@Autowired
private DataValidator<MobileApp> mobileAppValidator;
@Override
public MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp) {
log.trace("Executing saveMobileApp [{}]", mobileApp);
mobileAppValidator.validate(mobileApp, MobileApp::getTenantId);
try {
MobileApp savedMobileApp = mobileAppDao.save(tenantId, mobileApp);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedMobileApp).build());
@ -84,7 +80,7 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil
log.trace("Executing deleteMobileAppById [{}]", mobileAppId.getId());
mobileAppDao.removeById(tenantId, mobileAppId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(mobileAppId).build());
}
}
@Override
public MobileApp findMobileAppById(TenantId tenantId, MobileAppId mobileAppId) {
@ -99,7 +95,7 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil
List<MobileAppInfo> mobileAppInfos = new ArrayList<>();
mobileApps.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(mobileApp -> {
mobileAppInfos.add(new MobileAppInfo(mobileApp, oauth2ClientDao.findByMobileAppId(mobileApp.getUuidId()).stream()
.map(OAuth2Utils::toClientInfo)
.map(OAuth2ClientInfo::new)
.collect(Collectors.toList())));
});
return mobileAppInfos;
@ -113,7 +109,7 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil
return null;
}
return new MobileAppInfo(mobileApp, oauth2ClientDao.findByMobileAppId(mobileApp.getUuidId()).stream()
.map(OAuth2Utils::toClientInfo)
.map(OAuth2ClientInfo::new)
.collect(Collectors.toList()));
}

View File

@ -129,7 +129,7 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA
log.trace("Executing findOAuth2ClientInfosByTenantId tenantId=[{}]", tenantId);
return oauth2ClientDao.findByTenantId(tenantId.getId())
.stream()
.map(OAuth2Utils::toClientInfo)
.map(OAuth2ClientInfo::new)
.collect(Collectors.toList());
}

View File

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.dao.oauth2;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
@ -30,13 +29,4 @@ public class OAuth2Utils {
return client;
}
public static OAuth2ClientInfo toClientInfo(OAuth2Client oAuth2Client) {
OAuth2ClientInfo client = new OAuth2ClientInfo();
client.setId(oAuth2Client.getId());
client.setCreatedTime(oAuth2Client.getCreatedTime());
client.setTitle(oAuth2Client.getTitle());
client.setPlatforms(oAuth2Client.getPlatforms());
return client;
}
}

View File

@ -26,6 +26,7 @@ import jakarta.validation.ConstraintValidatorContext;
@Slf4j
public class StringLengthValidator implements ConstraintValidator<Length, Object> {
private int max;
private int min;
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
@ -35,14 +36,15 @@ public class StringLengthValidator implements ConstraintValidator<Length, Object
} else {
return true;
}
if (StringUtils.isEmpty(stringValue)) {
if (stringValue == null) {
return true;
}
return stringValue.length() <= max;
return stringValue.length() >= min && stringValue.length() <= max;
}
@Override
public void initialize(Length constraintAnnotation) {
this.max = constraintAnnotation.max();
this.min = constraintAnnotation.min();
}
}

View File

@ -1,36 +0,0 @@
/**
* Copyright © 2016-2024 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.dao.service.validator;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
@Component
@AllArgsConstructor
public class DomainDataValidator extends DataValidator<Domain> {
@Override
protected void validateDataImpl(TenantId tenantId, Domain domain) {
if (StringUtils.isEmpty(domain.getName())) {
throw new DataValidationException("Domain name should be specified!");
}
}
}

View File

@ -1,42 +0,0 @@
/**
* Copyright © 2016-2024 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.dao.service.validator;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
@Component
@AllArgsConstructor
public class MobileAppDataValidator extends DataValidator<MobileApp> {
@Override
protected void validateDataImpl(TenantId tenantId, MobileApp mobileApp) {
if (StringUtils.isEmpty(mobileApp.getPkgName())) {
throw new DataValidationException("Package should be specified!");
}
if (StringUtils.isEmpty(mobileApp.getAppSecret())) {
throw new DataValidationException("Application secret should be specified!");
}
if (mobileApp.getAppSecret().length() < 16) {
throw new DataValidationException("Application secret should be at least 16 characters!");
}
}
}

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.sql.domain;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.domain.DomainOauth2Client;
import org.thingsboard.server.common.data.id.DomainId;
@ -82,5 +83,9 @@ public class JpaDomainDao extends JpaAbstractDao<DomainEntity, Domain> implement
domainRepository.deleteByTenantId(tenantId.getId());
}
@Override
public EntityType getEntityType() {
return EntityType.DOMAIN;
}
}

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.sql.mobile;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.MobileAppId;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
import org.thingsboard.server.common.data.id.TenantId;
@ -77,5 +78,10 @@ public class JpaMobileAppDao extends JpaAbstractDao<MobileAppEntity, MobileApp>
repository.deleteByTenantId(tenantId.getId());
}
@Override
public EntityType getEntityType() {
return EntityType.MOBILE_APP;
}
}

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.sql.oauth2;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.PlatformType;
@ -83,4 +84,9 @@ public class JpaOAuth2ClientDao extends JpaAbstractDao<OAuth2ClientEntity, OAuth
repository.deleteByTenantId(tenantId.getId());
}
@Override
public EntityType getEntityType() {
return EntityType.OAUTH2_CLIENT;
}
}

View File

@ -51,7 +51,7 @@ public class DomainServiceTest extends AbstractServiceTest {
@Test
public void testSaveDomain() {
Domain domain = validDomain(TenantId.SYS_TENANT_ID, "test.domain.com", true, true);
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "test.domain.com", true, true);
Domain savedDomain = domainService.saveDomain(SYSTEM_TENANT_ID, domain);
Domain retrievedDomain = domainService.findDomainById(savedDomain.getTenantId(), savedDomain.getId());
@ -87,7 +87,7 @@ public class DomainServiceTest extends AbstractServiceTest {
public void testGetTenantDomains() {
List<Domain> domains = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Domain oAuth2Client = validDomain(TenantId.SYS_TENANT_ID, StringUtils.randomAlphabetic(5), true, false);
Domain oAuth2Client = constructDomain(TenantId.SYS_TENANT_ID, StringUtils.randomAlphabetic(5), true, false);
Domain savedOauth2Client = domainService.saveDomain(SYSTEM_TENANT_ID, oAuth2Client);
domains.add(savedOauth2Client);
}
@ -102,7 +102,7 @@ public class DomainServiceTest extends AbstractServiceTest {
OAuth2Client savedOauth2Client = oAuth2ClientService.saveOAuth2Client(SYSTEM_TENANT_ID, oAuth2Client);
List<OAuth2ClientInfo> infos = oAuth2ClientService.findOAuth2ClientInfosByTenantId(TenantId.SYS_TENANT_ID);
Domain domain = validDomain(TenantId.SYS_TENANT_ID, "test.domain.com", true, true);
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "test.domain.com", true, true);
Domain savedDomain = domainService.saveDomain(SYSTEM_TENANT_ID, domain);
domainService.updateOauth2Clients(TenantId.SYS_TENANT_ID, savedDomain.getId(), List.of(savedOauth2Client.getId()));
@ -116,7 +116,7 @@ public class DomainServiceTest extends AbstractServiceTest {
assertThat(oauth2LoginInfo).containsOnly(new OAuth2ClientLoginInfo(savedOauth2Client.getName(), savedOauth2Client.getLoginButtonIcon(), String.format(OAUTH2_AUTHORIZATION_PATH_TEMPLATE, savedOauth2Client.getUuidId().toString())));
}
private Domain validDomain(TenantId tenantId, String domainName, boolean oauth2Enabled, boolean propagateToEdge) {
private Domain constructDomain(TenantId tenantId, String domainName, boolean oauth2Enabled, boolean propagateToEdge) {
Domain domain = new Domain();
domain.setTenantId(tenantId);
domain.setName(domainName);
@ -125,7 +125,4 @@ public class DomainServiceTest extends AbstractServiceTest {
return domain;
}
}

View File

@ -22,15 +22,16 @@ import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.oauth2.OAuth2ClientService;
import org.thingsboard.server.dao.oauth2.OAuth2Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@DaoSqlTest
public class OAuth2ClientServiceTest extends AbstractServiceTest {
@ -58,6 +59,35 @@ public class OAuth2ClientServiceTest extends AbstractServiceTest {
assertThat(retrievedOauth2Client2).isEqualTo(updatedOauth2Client);
}
@Test
public void testSaveOauth2ClientWithoutMapper() {
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "Test google client", List.of(PlatformType.ANDROID));
oAuth2Client.setMapperConfig(null);
assertThatThrownBy(() -> {
oAuth2ClientService.saveOAuth2Client(TenantId.SYS_TENANT_ID, oAuth2Client);
}).hasMessageContaining("mapperConfig must not be null");
}
@Test
public void testSaveOauth2ClientWithoutCustomConfig() {
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "Test google client", List.of(PlatformType.ANDROID));
oAuth2Client.getMapperConfig().setCustom(null);
assertThatThrownBy(() -> {
oAuth2ClientService.saveOAuth2Client(TenantId.SYS_TENANT_ID, oAuth2Client);
}).hasMessageContaining("Custom config should be specified!");
}
@Test
public void testSaveOauth2ClientWithoutCustomUrl() {
OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "Test google client", List.of(PlatformType.ANDROID));
oAuth2Client.getMapperConfig().setCustom(OAuth2CustomMapperConfig.builder().build());
assertThatThrownBy(() -> {
oAuth2ClientService.saveOAuth2Client(TenantId.SYS_TENANT_ID, oAuth2Client);
}).hasMessageContaining("Custom mapper URL should be specified!");
}
@Test
public void testGetTenantOAuth2Clients() {
List<OAuth2Client> oAuth2Clients = new ArrayList<>();
@ -70,7 +100,7 @@ public class OAuth2ClientServiceTest extends AbstractServiceTest {
assertThat(retrieved).containsOnlyOnceElementsOf(oAuth2Clients);
List<OAuth2ClientInfo> retrievedInfos = oAuth2ClientService.findOAuth2ClientInfosByTenantId(TenantId.SYS_TENANT_ID);
List<OAuth2ClientInfo> oAuth2ClientInfos = oAuth2Clients.stream().map(OAuth2Utils::toClientInfo).collect(Collectors.toList());
List<OAuth2ClientInfo> oAuth2ClientInfos = oAuth2Clients.stream().map(OAuth2ClientInfo::new).collect(Collectors.toList());
assertThat(retrievedInfos).containsOnlyOnceElementsOf(oAuth2ClientInfos);
}

View File

@ -86,6 +86,8 @@ import org.thingsboard.server.common.data.asset.AssetSearchQuery;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.audit.AuditLog;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.domain.DomainInfo;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeInfo;
@ -100,9 +102,12 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.DomainId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.MobileAppId;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationTemplateId;
import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.QueueId;
@ -117,6 +122,10 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.common.data.mobile.MobileAppInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate;
import org.thingsboard.server.common.data.oauth2.PlatformType;
@ -2070,13 +2079,103 @@ public class RestClient implements Closeable {
}, params).getBody();
}
// public OAuth2Info getCurrentOAuth2Info() {
// return restTemplate.getForEntity(baseURL + "/api/oauth2/config", OAuth2Info.class).getBody();
// }
//
// public OAuth2Info saveOAuth2Info(OAuth2Info oauth2Info) {
// return restTemplate.postForEntity(baseURL + "/api/oauth2/config", oauth2Info, OAuth2Info.class).getBody();
// }
public List<OAuth2ClientInfo> getTenantOAuth2Clients() {
return restTemplate.exchange(
baseURL + "/api/oauth2/client/infos",
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<List<OAuth2ClientInfo>>() {
}).getBody();
}
public Optional<OAuth2Client> getOauth2ClientById(OAuth2ClientId oAuth2ClientId) {
try {
ResponseEntity<OAuth2Client> oauth2Client = restTemplate.getForEntity(baseURL + "/api/oauth2/client/{id}", OAuth2Client.class, oAuth2ClientId.getId());
return Optional.ofNullable(oauth2Client.getBody());
} catch (HttpClientErrorException exception) {
if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
return Optional.empty();
} else {
throw exception;
}
}
}
public OAuth2Client saveOAuth2Client(OAuth2Client oAuth2Client) {
return restTemplate.postForEntity(baseURL + "/api/oauth2/client", oAuth2Client, OAuth2Client.class).getBody();
}
public void deleteOauth2CLient(OAuth2ClientId oAuth2ClientId) {
restTemplate.delete(baseURL + "/api/oauth2/client/{id}", oAuth2ClientId.getId());
}
public List<DomainInfo> getTenantDomainInfos() {
return restTemplate.exchange(
baseURL + "/api/domain/infos",
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<List<DomainInfo>>() {
}).getBody();
}
public Optional<DomainInfo> getDomainInfoById(DomainId domainId) {
try {
ResponseEntity<DomainInfo> domainInfo = restTemplate.getForEntity(baseURL + "/api/domain/info/{id}", DomainInfo.class, domainId.getId());
return Optional.ofNullable(domainInfo.getBody());
} catch (HttpClientErrorException exception) {
if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
return Optional.empty();
} else {
throw exception;
}
}
}
public Domain saveDomain(Domain domain) {
return restTemplate.postForEntity(baseURL + "/api/domain", domain, Domain.class).getBody();
}
public void deleteDomain(DomainId domainId) {
restTemplate.delete(baseURL + "/api/domain/{id}", domainId.getId());
}
public void updateDomainOauth2Clients(DomainId domainId, UUID[] oauth2ClientIds) {
restTemplate.postForLocation(baseURL + "/api/domain/{id}/oauth2Clients", oauth2ClientIds, domainId.getId());
}
public List<DomainInfo> getTenantMobileAppInfos() {
return restTemplate.exchange(
baseURL + "/api/mobileApp/infos",
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<List<DomainInfo>>() {
}).getBody();
}
public Optional<MobileAppInfo> getMobileAppInfoById(MobileAppId mobileAppId) {
try {
ResponseEntity<MobileAppInfo> mobileAppInfo = restTemplate.getForEntity(baseURL + "/api/mobileApp/info/{id}", MobileAppInfo.class, mobileAppId.getId());
return Optional.ofNullable(mobileAppInfo.getBody());
} catch (HttpClientErrorException exception) {
if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
return Optional.empty();
} else {
throw exception;
}
}
}
public MobileApp saveMobileApp(MobileApp mobileApp) {
return restTemplate.postForEntity(baseURL + "/api/mobileApp", mobileApp, MobileApp.class).getBody();
}
public void deleteMobileApp(MobileAppId mobileAppId) {
restTemplate.delete(baseURL + "/api/mobileApp/{id}", mobileAppId.getId());
}
public void updateMobileAppOauth2Clients(MobileAppId mobileAppId, UUID[] oauth2ClientIds) {
restTemplate.postForLocation(baseURL + "/api/mobileApp/{id}/oauth2Clients", oauth2ClientIds, mobileAppId.getId());
}
public String getLoginProcessingUrl() {
return restTemplate.getForEntity(baseURL + "/api/oauth2/loginProcessingUrl", String.class).getBody();