From af719050a0cd8fbdeb2f9fc0a13755ad1ad9ce81 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 22 Oct 2024 15:03:48 +0300 Subject: [PATCH] fixed bundle info when apps are missed --- .../main/data/upgrade/3.8.0/schema_update.sql | 8 ++++--- .../server/controller/OAuth2Controller.java | 21 ++++++++++--------- .../permission/SysAdminPermissions.java | 2 +- .../permission/TenantAdminPermissions.java | 1 + .../MobileAppBundleControllerTest.java | 12 +++++++++++ .../data/mobile/app/MobileAppVersionInfo.java | 4 ++-- .../data/mobile/layout/CustomMobilePage.java | 2 +- .../sql/mobile/MobileAppBundleRepository.java | 6 ++++-- .../main/resources/sql/schema-entities.sql | 2 +- 9 files changed, 38 insertions(+), 20 deletions(-) diff --git a/application/src/main/data/upgrade/3.8.0/schema_update.sql b/application/src/main/data/upgrade/3.8.0/schema_update.sql index 8884919cc5..6d71efd831 100644 --- a/application/src/main/data/upgrade/3.8.0/schema_update.sql +++ b/application/src/main/data/upgrade/3.8.0/schema_update.sql @@ -32,7 +32,7 @@ CREATE TABLE IF NOT EXISTS mobile_app_bundle ( ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS platform_type varchar(32), ADD COLUMN IF NOT EXISTS status varchar(32), - ADD COLUMN IF NOT EXISTS version_info varchar(16384), + ADD COLUMN IF NOT EXISTS version_info varchar(100000), ADD COLUMN IF NOT EXISTS store_info varchar(16384), DROP CONSTRAINT IF EXISTS mobile_app_pkg_name_key, DROP CONSTRAINT IF EXISTS mobile_app_unq_key; @@ -70,12 +70,14 @@ $$ -- duplicate app for iOS platform type iosAppId := uuid_generate_v4(); INSERT INTO mobile_app(id, created_time, tenant_id, pkg_name, app_secret, platform_type, status) - VALUES (iosAppId, (extract(epoch from now()) * 1000), mobileAppRecord.tenant_id, mobileAppRecord.pkg_name, mobileAppRecord.app_secret, 'IOS', mobileAppRecord.status); + VALUES (iosAppId, (extract(epoch from now()) * 1000), mobileAppRecord.tenant_id, mobileAppRecord.pkg_name, mobileAppRecord.app_secret, 'IOS', mobileAppRecord.status) + ON CONFLICT DO NOTHING; -- create bundle for android and iOS app generatedBundleId := uuid_generate_v4(); INSERT INTO mobile_app_bundle(id, created_time, tenant_id, title, android_app_id, ios_app_id, oauth2_enabled) VALUES (generatedBundleId, (extract(epoch from now()) * 1000), mobileAppRecord.tenant_id, - 'Autogenerated for ' || mobileAppRecord.pkg_name, mobileAppRecord.id, iosAppId, mobileAppRecord.oauth2_enabled); + 'Autogenerated for ' || mobileAppRecord.pkg_name, mobileAppRecord.id, iosAppId, mobileAppRecord.oauth2_enabled) + ON CONFLICT DO NOTHING; UPDATE mobile_app_bundle_oauth2_client SET mobile_app_bundle_id = generatedBundleId WHERE mobile_app_bundle_id = mobileAppRecord.id; END LOOP; END IF; 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 8a8055c4af..a235034756 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -59,6 +59,7 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DE import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; @RestController @TbCoreComponent @@ -104,8 +105,8 @@ public class OAuth2Controller extends BaseController { } } - @ApiOperation(value = "Save OAuth2 Client (saveOAuth2Client)", notes = SYSTEM_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @ApiOperation(value = "Save OAuth2 Client (saveOAuth2Client)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @PostMapping(value = "/oauth2/client") public OAuth2Client saveOAuth2Client(@RequestBody @Valid OAuth2Client oAuth2Client) throws Exception { TenantId tenantId = getTenantId(); @@ -114,8 +115,8 @@ public class OAuth2Controller extends BaseController { return tbOauth2ClientService.save(oAuth2Client, getCurrentUser()); } - @ApiOperation(value = "Get OAuth2 Client infos (findTenantOAuth2ClientInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @ApiOperation(value = "Get OAuth2 Client infos (findTenantOAuth2ClientInfos)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @GetMapping(value = "/oauth2/client/infos") public PageData findTenantOAuth2ClientInfos(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, @@ -134,7 +135,7 @@ public class OAuth2Controller extends BaseController { @ApiOperation(value = "Get OAuth2 Client infos By Ids (findTenantOAuth2ClientInfosByIds)", notes = "Fetch OAuth2 Client info objects based on the provided ids. ") - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @GetMapping(value = "/oauth2/client/infos", params = {"clientIds"}) public List findTenantOAuth2ClientInfosByIds( @Parameter(description = "A list of oauth2 ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true) @@ -143,8 +144,8 @@ public class OAuth2Controller extends BaseController { return oAuth2ClientService.findOAuth2ClientInfosByIds(getTenantId(), oAuth2ClientIds); } - @ApiOperation(value = "Get OAuth2 Client by id (getOAuth2ClientById)", notes = SYSTEM_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @ApiOperation(value = "Get OAuth2 Client by id (getOAuth2ClientById)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @GetMapping(value = "/oauth2/client/{id}") public OAuth2Client getOAuth2ClientById(@PathVariable UUID id) throws ThingsboardException { OAuth2ClientId oAuth2ClientId = new OAuth2ClientId(id); @@ -152,8 +153,8 @@ public class OAuth2Controller extends BaseController { } @ApiOperation(value = "Delete oauth2 client (deleteOauth2Client)", - notes = "Deletes the oauth2 client. Referencing non-existing oauth2 client Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAuthority('SYS_ADMIN')") + notes = "Deletes the oauth2 client. Referencing non-existing oauth2 client Id will cause an error." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @DeleteMapping(value = "/oauth2/client/{id}") public void deleteOauth2Client(@PathVariable UUID id) throws Exception { OAuth2ClientId oAuth2ClientId = new OAuth2ClientId(id); @@ -165,7 +166,7 @@ public class OAuth2Controller extends BaseController { "double quotes. After successful authentication with OAuth2 provider, it makes a redirect to this path so that the platform can do " + "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')") + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @GetMapping(value = "/oauth2/loginProcessingUrl") public String getLoginProcessingUrl() throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.OAUTH2_CLIENT, Operation.READ); diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java index b3210ea68a..875976465d 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java @@ -35,7 +35,7 @@ public class SysAdminPermissions extends AbstractPermissions { put(Resource.USER, userPermissionChecker); put(Resource.WIDGETS_BUNDLE, systemEntityPermissionChecker); put(Resource.WIDGET_TYPE, systemEntityPermissionChecker); - put(Resource.OAUTH2_CLIENT, PermissionChecker.allowAllPermissionChecker); + put(Resource.OAUTH2_CLIENT, systemEntityPermissionChecker); put(Resource.MOBILE_APP, systemEntityPermissionChecker); put(Resource.MOBILE_APP_BUNDLE, systemEntityPermissionChecker); put(Resource.DOMAIN, PermissionChecker.allowAllPermissionChecker); diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java index a0ef8a1766..c63121e60b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java @@ -51,6 +51,7 @@ public class TenantAdminPermissions extends AbstractPermissions { put(Resource.VERSION_CONTROL, PermissionChecker.allowAllPermissionChecker); put(Resource.NOTIFICATION, tenantEntityPermissionChecker); put(Resource.MOBILE_APP_SETTINGS, new PermissionChecker.GenericPermissionChecker(Operation.READ)); + put(Resource.OAUTH2_CLIENT, tenantEntityPermissionChecker); put(Resource.MOBILE_APP, tenantEntityPermissionChecker); put(Resource.MOBILE_APP_BUNDLE, tenantEntityPermissionChecker); } diff --git a/application/src/test/java/org/thingsboard/server/controller/MobileAppBundleControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/MobileAppBundleControllerTest.java index 9e7204a355..1030a6bd9c 100644 --- a/application/src/test/java/org/thingsboard/server/controller/MobileAppBundleControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/MobileAppBundleControllerTest.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.service.DaoSqlTest; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -99,6 +100,17 @@ public class MobileAppBundleControllerTest extends AbstractControllerTest { assertThat(createdMobileAppBundle.getIosAppId()).isEqualTo(iosApp.getId()); } + @Test + public void testSaveMobileAppBundleWithoutApps() throws Exception { + MobileAppBundle mobileAppBundle = new MobileAppBundle(); + mobileAppBundle.setTitle("Test bundle"); + + MobileAppBundle savedAppBundle = doPost("/api/mobile/bundle", mobileAppBundle, MobileAppBundle.class); + MobileAppBundleInfo retrievedMobileAppBundleInfo = doGet("/api/mobile/bundle/info/{id}", MobileAppBundleInfo.class, savedAppBundle.getId().getId()); + assertThat(retrievedMobileAppBundleInfo).isEqualTo(new MobileAppBundleInfo(savedAppBundle, null, null, false, + Collections.emptyList())); + } + @Test public void testUpdateMobileAppBundleOauth2Clients() throws Exception { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileAppVersionInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileAppVersionInfo.java index e177aed4a5..2ed6e962ec 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileAppVersionInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileAppVersionInfo.java @@ -35,7 +35,7 @@ public class MobileAppVersionInfo { private String minVersion; @Schema(description = "Release notes of minimum supported version") - @Length(fieldName = "minVersionReleaseNotes", max = 10000) + @Length(fieldName = "minVersionReleaseNotes", max = 40000) private String minVersionReleaseNotes; @Schema(description = "Latest supported version") @@ -43,7 +43,7 @@ public class MobileAppVersionInfo { private String latestVersion; @Schema(description = "Release notes of latest supported version") - @Length(fieldName = "latestVersionReleaseNotes", max = 10000) + @Length(fieldName = "latestVersionReleaseNotes", max = 40000) private String latestVersionReleaseNotes; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/CustomMobilePage.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/CustomMobilePage.java index 114e5930d3..d2e4db347c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/CustomMobilePage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/CustomMobilePage.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.Views; @EqualsAndHashCode(callSuper = true) public class CustomMobilePage extends AbstractMobilePage { - @Schema(description = "Path", example = "") + @Schema(description = "Path to custom page", example = "/alarmDetails/868c7083-032d-4f52-b8b4-7859aebb6a4e") @JsonView(Views.Public.class) private String path; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/MobileAppBundleRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/MobileAppBundleRepository.java index 982ff3c9ca..9aff6af3f1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/MobileAppBundleRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/mobile/MobileAppBundleRepository.java @@ -30,7 +30,8 @@ import java.util.UUID; public interface MobileAppBundleRepository extends JpaRepository { - @Query("SELECT new org.thingsboard.server.dao.model.sql.MobileAppBundleInfoEntity(b, andApp.pkgName, iosApp.pkgName, (andApp.status = 'PUBLISHED' or iosApp.status = 'PUBLISHED')) " + + @Query("SELECT new org.thingsboard.server.dao.model.sql.MobileAppBundleInfoEntity(b, andApp.pkgName, iosApp.pkgName, " + + "((andApp.status IS NOT NULL AND andApp.status = 'PUBLISHED') OR (iosApp.status IS NOT NULL AND iosApp.status = 'PUBLISHED'))) " + "FROM MobileAppBundleEntity b " + "LEFT JOIN MobileAppEntity andApp on b.androidAppId = andApp.id " + "LEFT JOIN MobileAppEntity iosApp on b.iosAppID = iosApp.id " + @@ -40,7 +41,8 @@ public interface MobileAppBundleRepository extends JpaRepository