renamed db column, added validation on mobile app creation

This commit is contained in:
dashevchenko 2024-10-11 11:59:32 +03:00
parent 5790ee1642
commit 119354a441
7 changed files with 82 additions and 11 deletions

View File

@ -33,7 +33,7 @@ CREATE TABLE IF NOT EXISTS mobile_app_bundle (
ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS platform_type varchar(32), 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 status varchar(32),
ADD COLUMN IF NOT EXISTS version_info varchar(16384), ADD COLUMN IF NOT EXISTS version_info varchar(16384),
ADD COLUMN IF NOT EXISTS qr_code_config varchar(16384), ADD COLUMN IF NOT EXISTS store_info varchar(16384),
DROP CONSTRAINT IF EXISTS mobile_app_pkg_name_key; DROP CONSTRAINT IF EXISTS mobile_app_pkg_name_key;
-- rename mobile_app_oauth2_client to mobile_app_bundle_oauth2_client -- rename mobile_app_oauth2_client to mobile_app_bundle_oauth2_client
@ -107,7 +107,7 @@ $$
SELECT id into androidAppId FROM mobile_app WHERE pkg_name = qrCodeRecord.android_config::jsonb ->> 'appPackage' AND platform_type = 'ANDROID'; SELECT id into androidAppId FROM mobile_app WHERE pkg_name = qrCodeRecord.android_config::jsonb ->> 'appPackage' AND platform_type = 'ANDROID';
IF androidAppId IS NULL THEN IF androidAppId IS NULL THEN
androidAppId := uuid_generate_v4(); androidAppId := uuid_generate_v4();
INSERT INTO mobile_app(id, created_time, tenant_id, pkg_name, platform_type, status, qr_code_config) INSERT INTO mobile_app(id, created_time, tenant_id, pkg_name, platform_type, status, store_info)
VALUES (androidAppId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id, VALUES (androidAppId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id,
qrCodeRecord.android_config::jsonb ->> 'appPackage', 'ANDROID', 'PUBLISHED', qrCodeRecord.android_config::jsonb - 'appPackage'); qrCodeRecord.android_config::jsonb ->> 'appPackage', 'ANDROID', 'PUBLISHED', qrCodeRecord.android_config::jsonb - 'appPackage');
generatedBundleId := uuid_generate_v4(); generatedBundleId := uuid_generate_v4();
@ -115,7 +115,7 @@ $$
VALUES (generatedBundleId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id, 'App bundle for qr code', androidAppId); VALUES (generatedBundleId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id, 'App bundle for qr code', androidAppId);
UPDATE qr_code_settings SET mobile_app_bundle_id = generatedBundleId WHERE id = qrCodeRecord.id; UPDATE qr_code_settings SET mobile_app_bundle_id = generatedBundleId WHERE id = qrCodeRecord.id;
ELSE ELSE
UPDATE mobile_app SET qr_code_config = qrCodeRecord.android_config::jsonb - 'appPackage' WHERE id = androidAppId; UPDATE mobile_app SET store_info = qrCodeRecord.android_config::jsonb - 'appPackage' WHERE id = androidAppId;
UPDATE qr_code_settings SET mobile_app_bundle_id = (SELECT id FROM mobile_app_bundle WHERE mobile_app_bundle.android_app_id = androidAppId) WHERE id = qrCodeRecord.id; UPDATE qr_code_settings SET mobile_app_bundle_id = (SELECT id FROM mobile_app_bundle WHERE mobile_app_bundle.android_app_id = androidAppId) WHERE id = qrCodeRecord.id;
END IF; END IF;
@ -124,7 +124,7 @@ $$
SELECT id into iosAppId FROM mobile_app WHERE pkg_name = iosPkgName AND platform_type = 'IOS'; SELECT id into iosAppId FROM mobile_app WHERE pkg_name = iosPkgName AND platform_type = 'IOS';
IF iosAppId IS NULL THEN IF iosAppId IS NULL THEN
iosAppId := uuid_generate_v4(); iosAppId := uuid_generate_v4();
INSERT INTO mobile_app(id, created_time, tenant_id, pkg_name, platform_type, status, qr_code_config) INSERT INTO mobile_app(id, created_time, tenant_id, pkg_name, platform_type, status, store_info)
VALUES (iosAppId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id, VALUES (iosAppId, (extract(epoch from now()) * 1000), qrCodeRecord.tenant_id,
iosPkgName, 'IOS', 'PUBLISHED', qrCodeRecord.ios_config); iosPkgName, 'IOS', 'PUBLISHED', qrCodeRecord.ios_config);
IF generatedBundleId IS NULL THEN IF generatedBundleId IS NULL THEN
@ -136,7 +136,7 @@ $$
UPDATE mobile_app_bundle SET ios_app_id = iosAppId WHERE id = generatedBundleId; UPDATE mobile_app_bundle SET ios_app_id = iosAppId WHERE id = generatedBundleId;
END IF; END IF;
ELSE ELSE
UPDATE mobile_app SET qr_code_config = qrCodeRecord.ios_config WHERE id = iosAppId; UPDATE mobile_app SET store_info = qrCodeRecord.ios_config WHERE id = iosAppId;
UPDATE qr_code_settings SET mobile_app_bundle_id = (SELECT id FROM mobile_app_bundle WHERE mobile_app_bundle.ios_app_id = iosAppId) WHERE id = qrCodeRecord.id; UPDATE qr_code_settings SET mobile_app_bundle_id = (SELECT id FROM mobile_app_bundle WHERE mobile_app_bundle.ios_app_id = iosAppId) WHERE id = qrCodeRecord.id;
END IF; END IF;
END LOOP; END LOOP;

View File

@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.service.DataValidator;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -42,10 +43,13 @@ public class MobileAppServiceImpl extends AbstractEntityService implements Mobil
@Autowired @Autowired
private MobileAppDao mobileAppDao; private MobileAppDao mobileAppDao;
@Autowired
private DataValidator<MobileApp> mobileAppDataValidator;
@Override @Override
public MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp) { public MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp) {
log.trace("Executing saveMobileApp [{}]", mobileApp); log.trace("Executing saveMobileApp [{}]", mobileApp);
mobileAppDataValidator.validate(mobileApp, a -> tenantId);
try { try {
MobileApp savedMobileApp = mobileAppDao.save(tenantId, mobileApp); MobileApp savedMobileApp = mobileAppDao.save(tenantId, mobileApp);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedMobileApp).build()); eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedMobileApp).build());

View File

@ -451,7 +451,7 @@ public class ModelConstants {
public static final String MOBILE_APP_PLATFORM_TYPE_PROPERTY = "platform_type"; public static final String MOBILE_APP_PLATFORM_TYPE_PROPERTY = "platform_type";
public static final String MOBILE_APP_STATUS_PROPERTY = "status"; public static final String MOBILE_APP_STATUS_PROPERTY = "status";
public static final String MOBILE_APP_VERSION_INFO_PROPERTY = "version_info"; public static final String MOBILE_APP_VERSION_INFO_PROPERTY = "version_info";
public static final String MOBILE_APP_QR_CODE_CONFIG_PROPERTY = "qr_code_config"; public static final String MOBILE_APP_STORE_INFO_PROPERTY = "store_info";
/** /**
* Mobile application bundle constants. * Mobile application bundle constants.

View File

@ -67,8 +67,8 @@ public class MobileAppEntity extends BaseSqlEntity<MobileApp> {
private JsonNode versionInfo; private JsonNode versionInfo;
@Convert(converter = JsonConverter.class) @Convert(converter = JsonConverter.class)
@Column(name = ModelConstants.MOBILE_APP_QR_CODE_CONFIG_PROPERTY) @Column(name = ModelConstants.MOBILE_APP_STORE_INFO_PROPERTY)
private JsonNode qrCodeConfig; private JsonNode storeInfo;
public MobileAppEntity() { public MobileAppEntity() {
super(); super();
@ -84,7 +84,7 @@ public class MobileAppEntity extends BaseSqlEntity<MobileApp> {
this.platformType = mobile.getPlatformType(); this.platformType = mobile.getPlatformType();
this.status = mobile.getStatus(); this.status = mobile.getStatus();
this.versionInfo = toJson(mobile.getVersionInfo()); this.versionInfo = toJson(mobile.getVersionInfo());
this.qrCodeConfig = toJson(mobile.getStoreInfo()); this.storeInfo = toJson(mobile.getStoreInfo());
} }
@Override @Override
@ -100,7 +100,7 @@ public class MobileAppEntity extends BaseSqlEntity<MobileApp> {
mobile.setPlatformType(platformType); mobile.setPlatformType(platformType);
mobile.setStatus(status); mobile.setStatus(status);
mobile.setVersionInfo(fromJson(versionInfo, MobileAppVersionInfo.class)); mobile.setVersionInfo(fromJson(versionInfo, MobileAppVersionInfo.class));
mobile.setStoreInfo(fromJson(qrCodeConfig, StoreInfo.class)); mobile.setStoreInfo(fromJson(storeInfo, StoreInfo.class));
return mobile; return mobile;
} }
} }

View File

@ -0,0 +1,46 @@
/**
* 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.id.TenantId;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.common.data.oauth2.PlatformType;
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 (mobileApp.getPlatformType() == PlatformType.ANDROID) {
if (mobileApp.getStoreInfo() != null && mobileApp.getStoreInfo().isEnabled() &&
(mobileApp.getStoreInfo().getSha256CertFingerprints() == null || mobileApp.getStoreInfo().getStoreLink() == null)) {
throw new DataValidationException("Sha256CertFingerprints and store link are required");
}
} else if (mobileApp.getPlatformType() == PlatformType.IOS) {
if (mobileApp.getStoreInfo() != null && mobileApp.getStoreInfo().isEnabled() &&
(mobileApp.getStoreInfo().getAppId() == null || mobileApp.getStoreInfo().getStoreLink() == null)) {
throw new DataValidationException("AppId and store link are required");
}
} else {
throw new DataValidationException("Wrong application platform type");
}
}
}

View File

@ -16,18 +16,26 @@
package org.thingsboard.server.dao.service.validator; package org.thingsboard.server.dao.service.validator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.MobileAppBundleId; import org.thingsboard.server.common.data.id.MobileAppBundleId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mobile.MobileApp;
import org.thingsboard.server.common.data.mobile.QRCodeConfig; import org.thingsboard.server.common.data.mobile.QRCodeConfig;
import org.thingsboard.server.common.data.mobile.QrCodeSettings; import org.thingsboard.server.common.data.mobile.QrCodeSettings;
import org.thingsboard.server.common.data.mobile.StoreInfo;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.mobile.MobileAppDao;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
@Component @Component
@AllArgsConstructor @AllArgsConstructor
public class QrCodeSettingsDataValidator extends DataValidator<QrCodeSettings> { public class QrCodeSettingsDataValidator extends DataValidator<QrCodeSettings> {
@Autowired
MobileAppDao mobileAppDao;
@Override @Override
protected void validateDataImpl(TenantId tenantId, QrCodeSettings qrCodeSettings) { protected void validateDataImpl(TenantId tenantId, QrCodeSettings qrCodeSettings) {
MobileAppBundleId mobileAppBundleId = qrCodeSettings.getMobileAppBundleId(); MobileAppBundleId mobileAppBundleId = qrCodeSettings.getMobileAppBundleId();
@ -35,6 +43,19 @@ public class QrCodeSettingsDataValidator extends DataValidator<QrCodeSettings> {
if (!qrCodeSettings.isUseDefaultApp() && (mobileAppBundleId == null)) { if (!qrCodeSettings.isUseDefaultApp() && (mobileAppBundleId == null)) {
throw new DataValidationException("Mobile app bundle is required to use custom application!"); throw new DataValidationException("Mobile app bundle is required to use custom application!");
} }
if (!qrCodeSettings.isUseDefaultApp()){
MobileApp androidApp = mobileAppDao.findByBundleIdAndPlatformType(tenantId, mobileAppBundleId, PlatformType.ANDROID);
StoreInfo androidStoreInfo = androidApp.getStoreInfo();
if (androidStoreInfo == null) {
throw new DataValidationException("Android app store info is empty! ");
}
MobileApp iosApp = mobileAppDao.findByBundleIdAndPlatformType(tenantId, mobileAppBundleId, PlatformType.IOS);
StoreInfo iosStoreInfo = iosApp.getStoreInfo();
if (iosStoreInfo == null) {
throw new DataValidationException("IOS app store info is empty! ");
}
}
if (qrCodeConfig == null) { if (qrCodeConfig == null) {
throw new DataValidationException("Qr code configuration is required!"); throw new DataValidationException("Qr code configuration is required!");
} }

View File

@ -637,7 +637,7 @@ CREATE TABLE IF NOT EXISTS mobile_app (
platform_type varchar(32), platform_type varchar(32),
status varchar(32), status varchar(32),
version_info varchar(16384), version_info varchar(16384),
qr_code_config varchar(16384), store_info varchar(16384),
CONSTRAINT pkg_platform_unique UNIQUE (pkg_name, platform_type) CONSTRAINT pkg_platform_unique UNIQUE (pkg_name, platform_type)
); );