diff --git a/application/src/main/data/upgrade/3.7.0/schema_update.sql b/application/src/main/data/upgrade/3.7.0/schema_update.sql index 945051a3a2..dce84e3a40 100644 --- a/application/src/main/data/upgrade/3.7.0/schema_update.sql +++ b/application/src/main/data/upgrade/3.7.0/schema_update.sql @@ -24,10 +24,19 @@ ALTER TABLE domain ADD COLUMN IF NOT EXISTS oauth2_enabled boolean, ADD COLUMN IF NOT EXISTS edge_enabled boolean, ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080', DROP COLUMN IF EXISTS domain_scheme; + +-- delete duplicated domains +DELETE FROM domain d1 USING domain d2 WHERE d1.created_time < d2.created_time AND d1.domain_name = d2.domain_name; + ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS oauth2_enabled boolean, ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080'; -ALTER TABLE oauth2_client ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080'; -ALTER TABLE oauth2_client ADD COLUMN IF NOT EXISTS title varchar(100); + +-- delete duplicated apps +DELETE FROM mobile_app m1 USING mobile_app m2 WHERE m1.created_time < m2.created_time AND m1.pkg_name = m2.pkg_name; + +ALTER TABLE oauth2_client ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080', + ADD COLUMN IF NOT EXISTS title varchar(100); +UPDATE oauth2_client SET title = additional_info::jsonb->>'providerName' WHERE additional_info IS NOT NULL; CREATE TABLE IF NOT EXISTS domain_oauth2_client ( domain_id uuid NOT NULL, @@ -43,13 +52,11 @@ CREATE TABLE IF NOT EXISTS mobile_app_oauth2_client ( CONSTRAINT fk_oauth2_client FOREIGN KEY (oauth2_client_id) REFERENCES oauth2_client(id) ON DELETE CASCADE ); +-- migrate oauth2_params table DO $$ BEGIN IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'oauth2_params') THEN - -- delete duplicated domains - DELETE FROM domain d1 USING domain d2 WHERE d1.created_time < d2.created_time AND d1.domain_name = d2.domain_name; - UPDATE domain SET oauth2_enabled = p.enabled, edge_enabled = p.edge_enabled FROM oauth2_params p WHERE p.id = domain.oauth2_params_id; @@ -68,7 +75,6 @@ $$ ALTER TABLE mobile_app RENAME CONSTRAINT oauth2_mobile_pkey TO mobile_app_pkey; ALTER TABLE domain RENAME CONSTRAINT oauth2_domain_pkey TO domain_pkey; ALTER TABLE oauth2_client RENAME CONSTRAINT oauth2_registration_pkey TO oauth2_client_pkey; - UPDATE oauth2_client SET title = additional_info::jsonb->>'providerName' WHERE additional_info IS NOT NULL; ALTER TABLE domain DROP COLUMN oauth2_params_id; ALTER TABLE mobile_app DROP COLUMN oauth2_params_id; diff --git a/application/src/main/java/org/thingsboard/server/controller/DomainController.java b/application/src/main/java/org/thingsboard/server/controller/DomainController.java index 33de93cdd7..da0eeababf 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DomainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DomainController.java @@ -63,7 +63,7 @@ public class DomainController extends BaseController { "The newly created Domain Id will be present in the response. " + "Specify existing Domain Id to update the domain. " + "Referencing non-existing Domain Id will cause 'Not Found' error." + - "\n\nDomain name is unique for entire platform setup.\n\n") + "\n\nDomain name is unique for entire platform setup.\n\n" + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @PostMapping(value = "/domain") public Domain saveDomain( @@ -104,13 +104,13 @@ public class DomainController extends BaseController { } @ApiOperation(value = "Delete Domain by ID (deleteDomain)", - notes = "Deletes Domain by ID. Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + notes = "Deletes Domain by ID. Referencing non-existing asset Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @DeleteMapping(value = "/domain/{id}") public void deleteDomain(@PathVariable UUID id) throws Exception { DomainId domainId = new DomainId(id); - checkDomainId(domainId, Operation.DELETE); - domainService.deleteDomainById(getTenantId(), domainId); + Domain domain = checkDomainId(domainId, Operation.DELETE); + tbDomainService.delete(domain, getCurrentUser()); } } diff --git a/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java b/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java index 0f39d8f0ea..06e2c991fa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java +++ b/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java @@ -64,7 +64,7 @@ public class MobileAppController extends BaseController { "The newly created Mobile App Id will be present in the response. " + "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") + "\n\nMobile app package name is unique for entire platform setup.\n\n" + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @PostMapping(value = "/mobileApp") public MobileApp saveMobileApp( @@ -106,13 +106,13 @@ public class MobileAppController extends BaseController { } @ApiOperation(value = "Delete Mobile App by ID (deleteMobileApp)", - notes = "Deletes Mobile App by ID. Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + notes = "Deletes Mobile App by ID. Referencing non-existing asset Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @DeleteMapping(value = "/mobileApp/{id}") public void deleteMobileApp(@PathVariable UUID id) throws Exception { MobileAppId mobileAppId = new MobileAppId(id); - checkMobileAppId(mobileAppId, Operation.DELETE); - mobileAppService.deleteMobileAppById(getTenantId(), mobileAppId); + MobileApp mobileApp = checkMobileAppId(mobileAppId, Operation.DELETE); + tbMobileAppService.delete(mobileApp, getCurrentUser()); } } diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java index 7134bf1fd5..001438ce43 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -51,7 +51,6 @@ import java.util.List; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; @RestController @TbCoreComponent @@ -100,7 +99,7 @@ public class OAuth2Controller extends BaseController { } } - @ApiOperation(value = "Save OAuth2 Client Registration (saveOAuth2Client)", notes = SYSTEM_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Save OAuth2 Client (saveOAuth2Client)", notes = SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @PostMapping(value = "/oauth2/client") public OAuth2Client saveOAuth2Client(@RequestBody @Valid OAuth2Client oAuth2Client) throws Exception { @@ -126,7 +125,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) + notes = "Deletes the asset and all the relations (from and to the asset). Referencing non-existing asset Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @DeleteMapping(value = "/oauth2/client/{id}") public void deleteOauth2Client(@PathVariable UUID id) throws Exception { diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 4bef0d420a..75ac97881c 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -137,6 +137,9 @@ public class ThingsboardInstallService { entityDatabaseSchemaService.createCustomerTitleUniqueConstraintIfNotExists(); systemDataLoaderService.updateDefaultNotificationConfigs(false); systemDataLoaderService.updateSecuritySettings(); + case "3.7.0": + log.info("Upgrading ThingsBoard from version 3.7.0 to 3.7.1 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.7.0"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 86d922c305..000c0536cc 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -121,6 +121,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService case "3.6.4": updateSchema("3.6.4", 3006004, "3.7.0", 3007000, null); break; + case "3.7.0": + updateSchema("3.7.0", 3007000, "3.7.1", 3007001, null); + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index b83a1b567c..59c1a50fa1 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -99,6 +99,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.oauth2.MapperType; +import org.thingsboard.server.common.data.oauth2.OAuth2Client; +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.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; @@ -1109,4 +1114,39 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { tbTenantProfileService.save(TenantId.SYS_TENANT_ID, tenantProfile, oldTenantProfile); } + protected OAuth2Client validClientInfo(TenantId tenantId, String title) { + return validClientInfo(tenantId, title, null); + } + + protected OAuth2Client validClientInfo(TenantId tenantId, String title, List 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; + } + } diff --git a/application/src/test/java/org/thingsboard/server/controller/DomainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DomainControllerTest.java index 9fe161d936..d2ade5de11 100644 --- a/application/src/test/java/org/thingsboard/server/controller/DomainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DomainControllerTest.java @@ -140,39 +140,4 @@ public class DomainControllerTest extends AbstractControllerTest { return domain; } - protected OAuth2Client validClientInfo(TenantId tenantId, String title) { - return validClientInfo(tenantId, title, null); - } - - protected OAuth2Client validClientInfo(TenantId tenantId, String title, List 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; - } - } diff --git a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java index e796c7346a..6b46e64cfe 100644 --- a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java @@ -60,7 +60,6 @@ import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataUpdate; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.UUID; import java.util.concurrent.TimeUnit; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -361,8 +360,11 @@ public class HomePageApiTest extends AbstractControllerTest { Assert.assertTrue(featuresInfo.isNotificationEnabled()); Assert.assertFalse(featuresInfo.isOauthEnabled()); - Domain domain = createDomain(TenantId.SYS_TENANT_ID, "mydomain", true); - doPost("/api/domain", domain).andExpect(status().isOk()); + OAuth2Client oAuth2Client = validClientInfo(TenantId.SYS_TENANT_ID, "test google client"); + OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); + + Domain domain = createDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true); + doPost("/api/domain?oauth2ClientIds=" + savedOAuth2Client.getId().getId(), domain, Domain.class); featuresInfo = doGet("/api/admin/featuresInfo", FeaturesInfo.class); Assert.assertNotNull(featuresInfo); @@ -484,38 +486,13 @@ public class HomePageApiTest extends AbstractControllerTest { return doPostWithResponse("/api/entitiesQuery/count", query, Long.class); } - private Domain createDomain(TenantId tenantId, String domainName, boolean oauth2Enabled) { + private Domain createDomain(TenantId tenantId, String domainName, boolean oauth2Enabled, boolean edgeEnabled) { Domain domain = new Domain(); domain.setTenantId(tenantId); domain.setName(domainName); domain.setOauth2Enabled(oauth2Enabled); + domain.setPropagateToEdge(edgeEnabled); return domain; } - private OAuth2Client validRegistration() { - OAuth2Client oAuth2Client = new OAuth2Client(); - oAuth2Client.setClientId(UUID.randomUUID().toString()); -// .clientSecret(UUID.randomUUID().toString()) -// .authorizationUri(UUID.randomUUID().toString()) -// .accessTokenUri(UUID.randomUUID().toString()) -// .scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString())) -// .platforms(Collections.emptyList()) -// .userInfoUri(UUID.randomUUID().toString()) -// .userNameAttributeName(UUID.randomUUID().toString()) -// .jwkSetUri(UUID.randomUUID().toString()) -// .clientAuthenticationMethod(UUID.randomUUID().toString()) -// .loginButtonLabel(UUID.randomUUID().toString()) -// .mapperConfig( -// OAuth2MapperConfig.builder() -// .type(MapperType.CUSTOM) -// .custom( -// OAuth2CustomMapperConfig.builder() -// .url(UUID.randomUUID().toString()) -// .build() -// ) -// .build() -// ) -// .build(); - return oAuth2Client; - } } diff --git a/application/src/test/java/org/thingsboard/server/controller/MobileAppControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/MobileAppControllerTest.java index 3ba8bd29dd..efe6318428 100644 --- a/application/src/test/java/org/thingsboard/server/controller/MobileAppControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/MobileAppControllerTest.java @@ -142,39 +142,4 @@ public class MobileAppControllerTest extends AbstractControllerTest { return MobileApp; } - protected OAuth2Client validClientInfo(TenantId tenantId, String title) { - return validClientInfo(tenantId, title, null); - } - - protected OAuth2Client validClientInfo(TenantId tenantId, String title, List 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; - } - } diff --git a/application/src/test/java/org/thingsboard/server/controller/Oauth2ClientControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/Oauth2ClientControllerTest.java index 8ab7233286..42371c8769 100644 --- a/application/src/test/java/org/thingsboard/server/controller/Oauth2ClientControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/Oauth2ClientControllerTest.java @@ -80,39 +80,4 @@ public class Oauth2ClientControllerTest extends AbstractControllerTest { .andExpect(status().isNotFound()); } - protected OAuth2Client validClientInfo(TenantId tenantId, String title) { - return validClientInfo(tenantId, title, null); - } - - protected OAuth2Client validClientInfo(TenantId tenantId, String title, List 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; - } - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/domain/Domain.java b/common/data/src/main/java/org/thingsboard/server/common/data/domain/Domain.java index 6b1853c890..e2414f11d8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/domain/Domain.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/domain/Domain.java @@ -19,7 +19,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; import lombok.ToString; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasName; @@ -30,7 +29,6 @@ import org.thingsboard.server.common.data.id.TenantId; @EqualsAndHashCode(callSuper = true) @Data @ToString -@NoArgsConstructor public class Domain extends BaseData implements HasTenantId, HasName { @Schema(description = "JSON object with Tenant Id") @@ -43,6 +41,14 @@ public class Domain extends BaseData implements HasTenantId, HasName { @Schema(description = "Whether OAuth2 settings are enabled on Edge or not") private boolean propagateToEdge; + public Domain() { + super(); + } + + public Domain(DomainId id) { + super(id); + } + public Domain(Domain domain) { super(domain); this.tenantId = domain.tenantId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/domain/DomainInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/domain/DomainInfo.java index 83ea9998df..335d5b1604 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/domain/DomainInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/domain/DomainInfo.java @@ -16,21 +16,17 @@ 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.id.DomainId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; import java.util.List; @EqualsAndHashCode(callSuper = true) @Data -@NoArgsConstructor -@AllArgsConstructor @Schema -public class DomainInfo extends Domain implements HasOauth2Clients { +public class DomainInfo extends Domain { @Schema(description = "List of available oauth2 client registration") private List oauth2ClientInfos; @@ -39,4 +35,12 @@ public class DomainInfo extends Domain implements HasOauth2Clients { super(domain); this.oauth2ClientInfos = oauth2ClientInfos; } + + public DomainInfo() { + super(); + } + + public DomainInfo(DomainId domainId) { + super(domainId); + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileApp.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileApp.java index ddbb3fcf58..3dad679532 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileApp.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileApp.java @@ -17,10 +17,10 @@ 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.NotBlank; import jakarta.validation.constraints.NotEmpty; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; import lombok.ToString; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasName; @@ -32,13 +32,12 @@ import org.thingsboard.server.common.data.validation.Length; @EqualsAndHashCode(callSuper = true) @Data @ToString -@NoArgsConstructor public class MobileApp extends BaseData implements HasTenantId, HasName { @Schema(description = "JSON object with Tenant Id") private TenantId tenantId; @Schema(description = "Application package name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) - @NotEmpty + @NotBlank private String pkgName; @Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty @@ -47,6 +46,14 @@ public class MobileApp extends BaseData implements HasTenantId, Has @Schema(description = "Whether OAuth2 settings are enabled or not") private boolean oauth2Enabled; + public MobileApp() { + super(); + } + + public MobileApp(MobileAppId id) { + super(id); + } + public MobileApp(MobileApp mobile) { super(mobile); this.tenantId = mobile.tenantId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileAppInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileAppInfo.java index 541f1e6753..9a0b0b3b1c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileAppInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/MobileAppInfo.java @@ -16,25 +16,17 @@ package org.thingsboard.server.common.data.mobile; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.ToString; -import org.thingsboard.server.common.data.oauth2.HasOauth2Clients; +import org.thingsboard.server.common.data.id.MobileAppId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; import java.util.List; @EqualsAndHashCode(callSuper = true) @Data -@ToString -@NoArgsConstructor -@AllArgsConstructor -@Builder @Schema -public class MobileAppInfo extends MobileApp implements HasOauth2Clients { +public class MobileAppInfo extends MobileApp { @Schema(description = "List of available oauth2 client registrations") private List oauth2ClientInfos; @@ -44,4 +36,12 @@ public class MobileAppInfo extends MobileApp implements HasOauth2Clients { this.oauth2ClientInfos = oauth2ClientInfos; } + public MobileAppInfo() { + super(); + } + + public MobileAppInfo(MobileAppId mobileAppId) { + super(mobileAppId); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/HasOauth2Clients.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/HasOauth2Clients.java deleted file mode 100644 index 86cdfd1d92..0000000000 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/HasOauth2Clients.java +++ /dev/null @@ -1,26 +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.common.data.oauth2; - - -import java.io.Serializable; -import java.util.List; - -public interface HasOauth2Clients extends Serializable { - - List getOauth2ClientInfos(); - -} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Client.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Client.java index a8a5f0eacd..7624a6ccd5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Client.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Client.java @@ -23,7 +23,6 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; import lombok.ToString; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.HasName; @@ -36,7 +35,6 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @Data @ToString(exclude = {"clientSecret"}) -@NoArgsConstructor public class OAuth2Client extends BaseDataWithAdditionalInfo implements HasName, HasTenantId { @Schema(description = "JSON object with Tenant Id") @@ -82,23 +80,31 @@ public class OAuth2Client extends BaseDataWithAdditionalInfo imp @Schema(description = "Additional info of OAuth2 client (e.g. providerName)", requiredMode = Schema.RequiredMode.REQUIRED) private JsonNode additionalInfo; - public OAuth2Client(OAuth2Client registration) { - super(registration); - this.tenantId = registration.tenantId; - this.title = registration.title; - this.mapperConfig = registration.mapperConfig; - this.clientId = registration.clientId; - this.clientSecret = registration.clientSecret; - this.authorizationUri = registration.authorizationUri; - this.accessTokenUri = registration.accessTokenUri; - this.scope = registration.scope; - this.userInfoUri = registration.userInfoUri; - this.userNameAttributeName = registration.userNameAttributeName; - this.jwkSetUri = registration.jwkSetUri; - this.clientAuthenticationMethod = registration.clientAuthenticationMethod; - this.loginButtonLabel = registration.loginButtonLabel; - this.loginButtonIcon = registration.loginButtonIcon; - this.platforms = registration.platforms; + public OAuth2Client() { + super(); + } + + public OAuth2Client(OAuth2ClientId id) { + super(id); + } + + public OAuth2Client(OAuth2Client oAuth2Client) { + super(oAuth2Client); + this.tenantId = oAuth2Client.tenantId; + this.title = oAuth2Client.title; + this.mapperConfig = oAuth2Client.mapperConfig; + this.clientId = oAuth2Client.clientId; + this.clientSecret = oAuth2Client.clientSecret; + this.authorizationUri = oAuth2Client.authorizationUri; + this.accessTokenUri = oAuth2Client.accessTokenUri; + this.scope = oAuth2Client.scope; + this.userInfoUri = oAuth2Client.userInfoUri; + this.userNameAttributeName = oAuth2Client.userNameAttributeName; + this.jwkSetUri = oAuth2Client.jwkSetUri; + this.clientAuthenticationMethod = oAuth2Client.clientAuthenticationMethod; + this.loginButtonLabel = oAuth2Client.loginButtonLabel; + this.loginButtonIcon = oAuth2Client.loginButtonIcon; + this.platforms = oAuth2Client.platforms; } @Override diff --git a/common/proto/src/main/proto/queue.proto b/common/proto/src/main/proto/queue.proto index 581b993120..974ec504fe 100644 --- a/common/proto/src/main/proto/queue.proto +++ b/common/proto/src/main/proto/queue.proto @@ -54,7 +54,10 @@ enum EntityTypeProto { NOTIFICATION_REQUEST = 31; NOTIFICATION = 32; NOTIFICATION_RULE = 33; - QUEUE_STATS = 34; + QUEUE_STATS = 34; + OAUTH2_CLIENT = 35; + DOMAIN = 36; + MOBILE_APP = 37; } /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/domain/DomainServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/domain/DomainServiceImpl.java index bb1c89b012..ee82b0cf8a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/domain/DomainServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/domain/DomainServiceImpl.java @@ -77,7 +77,7 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe @Override public void updateOauth2Clients(TenantId tenantId, DomainId domainId, List oAuth2ClientIds) { - log.trace("Executing addOauth2Clients, domainId [{}], oAuth2ClientIds [{}]", domainId, oAuth2ClientIds); + log.trace("Executing updateOauth2Clients, domainId [{}], oAuth2ClientIds [{}]", domainId, oAuth2ClientIds); Validator.validateId(tenantId, id -> INCORRECT_TENANT_ID + id); Validator.validateId(domainId, id -> INCORRECT_DOMAIN_ID + id); Validator.checkNotNull(oAuth2ClientIds, "Incorrect oAuth2ClientIds " + oAuth2ClientIds); @@ -118,7 +118,7 @@ public class DomainServiceImpl extends AbstractEntityService implements DomainSe @Override public List findDomainInfosByTenantId(TenantId tenantId) { - log.trace("Executing findDomainInfo [{}]", tenantId); + log.trace("Executing findDomainInfosByTenantId [{}]", tenantId); List domains = domainDao.findByTenantId(tenantId); List domainInfos = new ArrayList<>(); domains.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(domain -> { diff --git a/dao/src/main/java/org/thingsboard/server/dao/mobile/MobileAppServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/mobile/MobileAppServiceImpl.java index 6dc5d1c1f5..9466c3c42b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/mobile/MobileAppServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/mobile/MobileAppServiceImpl.java @@ -163,7 +163,7 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil @Override public void deleteMobileAppsByTenantId(TenantId tenantId) { - log.trace("Executing deleteDomainsByTenantId, tenantId [{}]", tenantId); + log.trace("Executing deleteMobileAppsByTenantId, tenantId [{}]", tenantId); Validator.validateId(tenantId, id -> INCORRECT_TENANT_ID + id); mobileAppDao.deleteByTenantId(tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java index 6cf944804d..d94f0c7fce 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java @@ -57,7 +57,7 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA @Override public List findOAuth2ClientLoginInfosByDomainName(String domainName) { - log.trace("Executing getOAuth2Clients [{}] ", domainName); + log.trace("Executing findOAuth2ClientLoginInfosByDomainName [{}] ", domainName); validateString(domainName, dn -> INCORRECT_DOMAIN_NAME + dn); return oauth2ClientDao.findEnabledByDomainName(domainName) .stream() @@ -67,7 +67,7 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA @Override public List findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType(String pkgName, PlatformType platformType) { - log.trace("Executing getOAuth2Clients pkgName=[{}] platformType=[{}]",pkgName, platformType); + log.trace("Executing findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType pkgName=[{}] platformType=[{}]",pkgName, platformType); return oauth2ClientDao.findEnabledByPckNameAndPlatformType(pkgName, platformType) .stream() .map(OAuth2Utils::toClientLoginInfo) @@ -108,7 +108,7 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA @Override @Transactional public void deleteOAuth2ClientById(TenantId tenantId, OAuth2ClientId oAuth2ClientId) { - log.trace("[{}][{}] Executing deleteOAuth2ClientById [{}]", tenantId, oAuth2ClientId); + log.trace("Executing deleteOAuth2ClientById [{}]", oAuth2ClientId); oauth2ClientDao.removeById(tenantId, oAuth2ClientId.getId()); eventPublisher.publishEvent(DeleteEntityEvent.builder() .tenantId(tenantId) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/JpaMobileAppDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/JpaMobileAppDao.java index 98442974f8..3ed91d722a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/JpaMobileAppDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/JpaMobileAppDao.java @@ -40,7 +40,7 @@ import java.util.UUID; @SqlDao public class JpaMobileAppDao extends JpaAbstractDao implements MobileAppDao { - private final MobileAppRepository repository; + private final MobileAppRepository mobileAppRepository; private final MobileAppOauth2ClientRepository mobileOauth2ProviderRepository; @Override @@ -50,12 +50,12 @@ public class JpaMobileAppDao extends JpaAbstractDao @Override protected JpaRepository getRepository() { - return repository; + return mobileAppRepository; } @Override public List findByTenantId(TenantId tenantId) { - return DaoUtil.convertDataList(repository.findByTenantId(tenantId.getId())); + return DaoUtil.convertDataList(mobileAppRepository.findByTenantId(tenantId.getId())); } @Override @@ -75,7 +75,7 @@ public class JpaMobileAppDao extends JpaAbstractDao @Override public void deleteByTenantId(TenantId tenantId) { - repository.deleteByTenantId(tenantId.getId()); + mobileAppRepository.deleteByTenantId(tenantId.getId()); } @Override diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 93adc65135..382b95603a 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -560,9 +560,9 @@ CREATE TABLE IF NOT EXISTS key_dictionary CREATE TABLE IF NOT EXISTS oauth2_client ( id uuid NOT NULL CONSTRAINT oauth2_client_pkey PRIMARY KEY, - tenant_id uuid NOT NULL, - title varchar(100) NOT NULL, created_time bigint NOT NULL, + tenant_id uuid NOT NULL, + title varchar(100) NOT NULL, additional_info varchar, client_id varchar(255), client_secret varchar(2048), @@ -595,22 +595,20 @@ CREATE TABLE IF NOT EXISTS oauth2_client ( CREATE TABLE IF NOT EXISTS domain ( id uuid NOT NULL CONSTRAINT domain_pkey PRIMARY KEY, - tenant_id uuid NOT NULL, created_time bigint NOT NULL, - domain_name varchar(255), + tenant_id uuid NOT NULL, + domain_name varchar(255) UNIQUE, oauth2_enabled boolean, - edge_enabled boolean, - CONSTRAINT domain_unq_key UNIQUE (domain_name) + edge_enabled boolean ); CREATE TABLE IF NOT EXISTS mobile_app ( id uuid NOT NULL CONSTRAINT mobile_app_pkey PRIMARY KEY, - tenant_id uuid, created_time bigint NOT NULL, - pkg_name varchar(255), + tenant_id uuid, + pkg_name varchar(255) UNIQUE, app_secret varchar(2048), - oauth2_enabled boolean, - CONSTRAINT mobile_app_unq_key UNIQUE (pkg_name) + oauth2_enabled boolean ); CREATE TABLE IF NOT EXISTS domain_oauth2_client (