Merge remote-tracking branch 'upstream/master' into mobileAppDeletion

This commit is contained in:
dashevchenko 2024-11-27 13:50:13 +02:00
commit a72753e86f
6 changed files with 44 additions and 16 deletions

View File

@ -38,6 +38,7 @@ import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.OAuth2ClientId;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.dao.oauth2.OAuth2Configuration;
import org.thingsboard.server.dao.oauth2.OAuth2ClientService;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -85,8 +86,9 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
String registrationId = this.resolveRegistrationId(request);
String redirectUriAction = getAction(request, "login");
String appPackage = getAppPackage(request);
String platform = getPlatform(request);
String appToken = getAppToken(request);
return resolve(request, registrationId, redirectUriAction, appPackage, appToken);
return resolve(request, registrationId, redirectUriAction, appPackage, platform, appToken);
}
@Override
@ -96,8 +98,9 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
}
String redirectUriAction = getAction(request, "authorize");
String appPackage = getAppPackage(request);
String platform = getPlatform(request);
String appToken = getAppToken(request);
return resolve(request, registrationId, redirectUriAction, appPackage, appToken);
return resolve(request, registrationId, redirectUriAction, appPackage, platform, appToken);
}
private String getAction(HttpServletRequest request, String defaultAction) {
@ -112,11 +115,15 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
return request.getParameter("pkg");
}
private String getPlatform(HttpServletRequest request) {
return request.getParameter("platform");
}
private String getAppToken(HttpServletRequest request) {
return request.getParameter("appToken");
}
private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String oauth2ClientId, String redirectUriAction, String appPackage, String appToken) {
private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String oauth2ClientId, String redirectUriAction, String appPackage, String platform, String appToken) {
if (oauth2ClientId == null) {
return null;
}
@ -132,11 +139,19 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
if (StringUtils.isEmpty(appToken)) {
throw new IllegalArgumentException("Invalid application token.");
} else {
String appSecret = this.oAuth2ClientService.findAppSecret(new OAuth2ClientId(UUID.fromString(oauth2ClientId)), appPackage);
if (StringUtils.isEmpty(appSecret)) {
throw new IllegalArgumentException("Invalid package: " + appPackage + ". No application secret found for Client Registration with given application package.");
String callbackUrlScheme;
if (platform != null) {
callbackUrlScheme = validateMobileAppToken(oauth2ClientId, appPackage, PlatformType.valueOf(platform), appToken);
} else {
// for backward compatibility with mobile apps of version 1.3.0 and less try to validate token with android and then ios app secret
try {
callbackUrlScheme = validateMobileAppToken(oauth2ClientId, appPackage, PlatformType.ANDROID, appToken);
} catch (IllegalArgumentException e) {
log.debug("Failed attempt to validate android application token, oauth client id: [{}], package name: [{}], appToken [{}] ",
oauth2ClientId, appPackage, appToken, e);
callbackUrlScheme = validateMobileAppToken(oauth2ClientId, appPackage, PlatformType.IOS, appToken);
}
}
String callbackUrlScheme = this.oAuth2AppTokenFactory.validateTokenAndGetCallbackUrlScheme(appPackage, appToken, appSecret);
attributes.put(TbOAuth2ParameterNames.CALLBACK_URL_SCHEME, callbackUrlScheme);
}
}
@ -174,6 +189,14 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
.build();
}
private String validateMobileAppToken(String oauth2ClientId, String appPackage, PlatformType platformType, String appToken) {
String appSecret = this.oAuth2ClientService.findAppSecret(new OAuth2ClientId(UUID.fromString(oauth2ClientId)), appPackage, platformType);
if (StringUtils.isEmpty(appSecret)) {
throw new IllegalArgumentException("Invalid package: " + appPackage + ". No application secret found for Client Registration with given application package.");
}
return this.oAuth2AppTokenFactory.validateTokenAndGetCallbackUrlScheme(appPackage, appToken, appSecret);
}
private String resolveRegistrationId(HttpServletRequest request) {
if (this.authorizationRequestMatcher.matches(request)) {
return this.authorizationRequestMatcher

View File

@ -40,7 +40,7 @@ public interface OAuth2ClientService extends EntityDaoService {
OAuth2Client findOAuth2ClientById(TenantId tenantId, OAuth2ClientId providerId);
String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName);
String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName, PlatformType platformType);
void deleteOAuth2ClientById(TenantId tenantId, OAuth2ClientId oAuth2ClientId);

View File

@ -38,7 +38,7 @@ public interface OAuth2ClientDao extends Dao<OAuth2Client> {
List<OAuth2Client> findByMobileAppBundleId(UUID mobileAppBundleId);
String findAppSecret(UUID id, String pkgName);
String findAppSecret(UUID id, String pkgName, PlatformType platformType);
void deleteByTenantId(UUID tenantId);

View File

@ -34,6 +34,7 @@ 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.service.DataValidator;
import org.thingsboard.server.dao.service.Validator;
import java.util.Comparator;
import java.util.List;
@ -45,6 +46,8 @@ import java.util.stream.Collectors;
@Service("OAuth2ClientService")
public class OAuth2ClientServiceImpl extends AbstractEntityService implements OAuth2ClientService {
private static final String PLATFORM_TYPE_IS_REQUIRED = "Platform type is required if package name is specified";
@Autowired
private OAuth2ClientDao oauth2ClientDao;
@Autowired
@ -90,9 +93,10 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA
}
@Override
public String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName) {
log.trace("Executing findAppSecret oAuth2ClientId = [{}] pkgName = [{}]", oAuth2ClientId, pkgName);
return oauth2ClientDao.findAppSecret(oAuth2ClientId.getId(), pkgName);
public String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName, PlatformType platformType) {
log.trace("Executing findAppSecret oAuth2ClientId = [{}] pkgName = [{}], platform [{}]", oAuth2ClientId, pkgName, platformType);
Validator.checkNotNull(platformType, PLATFORM_TYPE_IS_REQUIRED);
return oauth2ClientDao.findAppSecret(oAuth2ClientId.getId(), pkgName, platformType);
}
@Override

View File

@ -80,8 +80,8 @@ public class JpaOAuth2ClientDao extends JpaAbstractDao<OAuth2ClientEntity, OAuth
}
@Override
public String findAppSecret(UUID id, String pkgName) {
return repository.findAppSecret(id, pkgName);
public String findAppSecret(UUID id, String pkgName, PlatformType platformType) {
return repository.findAppSecret(id, pkgName, platformType.name());
}
@Override

View File

@ -72,9 +72,10 @@ public interface OAuth2ClientRepository extends JpaRepository<OAuth2ClientEntity
"LEFT JOIN MobileAppBundleOauth2ClientEntity bc ON bc.mobileAppBundleId = b.id " +
"LEFT JOIN OAuth2ClientEntity c ON bc.oauth2ClientId = c.id " +
"WHERE c.id = :clientId " +
"AND a.pkgName = :pkgName")
"AND a.pkgName = :pkgName and a.platformType = :platformType")
String findAppSecret(@Param("clientId") UUID id,
@Param("pkgName") String pkgName);
@Param("pkgName") String pkgName,
@Param("platformType") String platformType);
@Transactional
@Modifying