Commit cc531daaeee9f4ff2f38b3f2dcaa25f5854358a6
1 parent
8e4f8594
Add platform type filter for oauth2 registrations.
Showing
22 changed files
with
187 additions
and
44 deletions
@@ -96,6 +96,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | @@ -96,6 +96,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | ||
96 | authorization_uri varchar(255), | 96 | authorization_uri varchar(255), |
97 | token_uri varchar(255), | 97 | token_uri varchar(255), |
98 | scope varchar(255), | 98 | scope varchar(255), |
99 | + platforms varchar(255), | ||
99 | user_info_uri varchar(255), | 100 | user_info_uri varchar(255), |
100 | user_name_attribute_name varchar(255), | 101 | user_name_attribute_name varchar(255), |
101 | jwk_set_uri varchar(255), | 102 | jwk_set_uri varchar(255), |
@@ -26,9 +26,11 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -26,9 +26,11 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
26 | import org.springframework.web.bind.annotation.ResponseBody; | 26 | import org.springframework.web.bind.annotation.ResponseBody; |
27 | import org.springframework.web.bind.annotation.ResponseStatus; | 27 | import org.springframework.web.bind.annotation.ResponseStatus; |
28 | import org.springframework.web.bind.annotation.RestController; | 28 | import org.springframework.web.bind.annotation.RestController; |
29 | +import org.thingsboard.server.common.data.StringUtils; | ||
29 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 30 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
30 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; | 31 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
31 | import org.thingsboard.server.common.data.oauth2.OAuth2Info; | 32 | import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
33 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
32 | import org.thingsboard.server.dao.oauth2.OAuth2Configuration; | 34 | import org.thingsboard.server.dao.oauth2.OAuth2Configuration; |
33 | import org.thingsboard.server.queue.util.TbCoreComponent; | 35 | import org.thingsboard.server.queue.util.TbCoreComponent; |
34 | import org.thingsboard.server.service.security.permission.Operation; | 36 | import org.thingsboard.server.service.security.permission.Operation; |
@@ -51,7 +53,8 @@ public class OAuth2Controller extends BaseController { | @@ -51,7 +53,8 @@ public class OAuth2Controller extends BaseController { | ||
51 | @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) | 53 | @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) |
52 | @ResponseBody | 54 | @ResponseBody |
53 | public List<OAuth2ClientInfo> getOAuth2Clients(HttpServletRequest request, | 55 | public List<OAuth2ClientInfo> getOAuth2Clients(HttpServletRequest request, |
54 | - @RequestParam(required = false) String pkgName) throws ThingsboardException { | 56 | + @RequestParam(required = false) String pkgName, |
57 | + @RequestParam(required = false) String platform) throws ThingsboardException { | ||
55 | try { | 58 | try { |
56 | if (log.isDebugEnabled()) { | 59 | if (log.isDebugEnabled()) { |
57 | log.debug("Executing getOAuth2Clients: [{}][{}][{}]", request.getScheme(), request.getServerName(), request.getServerPort()); | 60 | log.debug("Executing getOAuth2Clients: [{}][{}][{}]", request.getScheme(), request.getServerName(), request.getServerPort()); |
@@ -61,7 +64,13 @@ public class OAuth2Controller extends BaseController { | @@ -61,7 +64,13 @@ public class OAuth2Controller extends BaseController { | ||
61 | log.debug("Header: {} {}", header, request.getHeader(header)); | 64 | log.debug("Header: {} {}", header, request.getHeader(header)); |
62 | } | 65 | } |
63 | } | 66 | } |
64 | - return oAuth2Service.getOAuth2Clients(MiscUtils.getScheme(request), MiscUtils.getDomainNameAndPort(request), pkgName); | 67 | + PlatformType platformType = null; |
68 | + if (StringUtils.isNotEmpty(platform)) { | ||
69 | + try { | ||
70 | + platformType = PlatformType.valueOf(platform); | ||
71 | + } catch (Exception e) {} | ||
72 | + } | ||
73 | + return oAuth2Service.getOAuth2Clients(MiscUtils.getScheme(request), MiscUtils.getDomainNameAndPort(request), pkgName, platformType); | ||
65 | } catch (Exception e) { | 74 | } catch (Exception e) { |
66 | throw handleException(e); | 75 | throw handleException(e); |
67 | } | 76 | } |
@@ -199,6 +199,7 @@ public class ThingsboardInstallService { | @@ -199,6 +199,7 @@ public class ThingsboardInstallService { | ||
199 | databaseEntitiesUpgradeService.upgradeDatabase("3.2.2"); | 199 | databaseEntitiesUpgradeService.upgradeDatabase("3.2.2"); |
200 | 200 | ||
201 | dataUpdateService.updateData("3.2.2"); | 201 | dataUpdateService.updateData("3.2.2"); |
202 | + systemDataLoaderService.createOAuth2Templates(); | ||
202 | 203 | ||
203 | log.info("Updating system data..."); | 204 | log.info("Updating system data..."); |
204 | systemDataLoaderService.updateSystemWidgets(); | 205 | systemDataLoaderService.updateSystemWidgets(); |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.oauth2; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.oauth2; | ||
18 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; | 18 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
19 | import org.thingsboard.server.common.data.oauth2.OAuth2Info; | 19 | import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
20 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | 20 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
21 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
21 | import org.thingsboard.server.common.data.oauth2.deprecated.OAuth2ClientRegistrationInfo; | 22 | import org.thingsboard.server.common.data.oauth2.deprecated.OAuth2ClientRegistrationInfo; |
22 | import org.thingsboard.server.common.data.oauth2.deprecated.OAuth2ClientsParams; | 23 | import org.thingsboard.server.common.data.oauth2.deprecated.OAuth2ClientsParams; |
23 | 24 | ||
@@ -25,7 +26,7 @@ import java.util.List; | @@ -25,7 +26,7 @@ import java.util.List; | ||
25 | import java.util.UUID; | 26 | import java.util.UUID; |
26 | 27 | ||
27 | public interface OAuth2Service { | 28 | public interface OAuth2Service { |
28 | - List<OAuth2ClientInfo> getOAuth2Clients(String domainScheme, String domainName, String pkgName); | 29 | + List<OAuth2ClientInfo> getOAuth2Clients(String domainScheme, String domainName, String pkgName, PlatformType platformType); |
29 | 30 | ||
30 | @Deprecated | 31 | @Deprecated |
31 | void saveOAuth2Params(OAuth2ClientsParams oauth2Params); | 32 | void saveOAuth2Params(OAuth2ClientsParams oauth2Params); |
@@ -46,6 +46,7 @@ public class OAuth2Registration extends SearchTextBasedWithAdditionalInfo<OAuth2 | @@ -46,6 +46,7 @@ public class OAuth2Registration extends SearchTextBasedWithAdditionalInfo<OAuth2 | ||
46 | private String clientAuthenticationMethod; | 46 | private String clientAuthenticationMethod; |
47 | private String loginButtonLabel; | 47 | private String loginButtonLabel; |
48 | private String loginButtonIcon; | 48 | private String loginButtonIcon; |
49 | + private List<PlatformType> platforms; | ||
49 | 50 | ||
50 | public OAuth2Registration(OAuth2Registration registration) { | 51 | public OAuth2Registration(OAuth2Registration registration) { |
51 | super(registration); | 52 | super(registration); |
@@ -62,6 +63,7 @@ public class OAuth2Registration extends SearchTextBasedWithAdditionalInfo<OAuth2 | @@ -62,6 +63,7 @@ public class OAuth2Registration extends SearchTextBasedWithAdditionalInfo<OAuth2 | ||
62 | this.clientAuthenticationMethod = registration.clientAuthenticationMethod; | 63 | this.clientAuthenticationMethod = registration.clientAuthenticationMethod; |
63 | this.loginButtonLabel = registration.loginButtonLabel; | 64 | this.loginButtonLabel = registration.loginButtonLabel; |
64 | this.loginButtonIcon = registration.loginButtonIcon; | 65 | this.loginButtonIcon = registration.loginButtonIcon; |
66 | + this.platforms = registration.platforms; | ||
65 | } | 67 | } |
66 | 68 | ||
67 | @Override | 69 | @Override |
@@ -39,5 +39,6 @@ public class OAuth2RegistrationInfo { | @@ -39,5 +39,6 @@ public class OAuth2RegistrationInfo { | ||
39 | private String clientAuthenticationMethod; | 39 | private String clientAuthenticationMethod; |
40 | private String loginButtonLabel; | 40 | private String loginButtonLabel; |
41 | private String loginButtonIcon; | 41 | private String loginButtonIcon; |
42 | + private List<PlatformType> platforms; | ||
42 | private JsonNode additionalInfo; | 43 | private JsonNode additionalInfo; |
43 | } | 44 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.oauth2; | ||
17 | + | ||
18 | +public enum PlatformType { | ||
19 | + WEB, ANDROID, IOS | ||
20 | +} |
@@ -433,6 +433,7 @@ public class ModelConstants { | @@ -433,6 +433,7 @@ public class ModelConstants { | ||
433 | public static final String OAUTH2_AUTHORIZATION_URI_PROPERTY = "authorization_uri"; | 433 | public static final String OAUTH2_AUTHORIZATION_URI_PROPERTY = "authorization_uri"; |
434 | public static final String OAUTH2_TOKEN_URI_PROPERTY = "token_uri"; | 434 | public static final String OAUTH2_TOKEN_URI_PROPERTY = "token_uri"; |
435 | public static final String OAUTH2_SCOPE_PROPERTY = "scope"; | 435 | public static final String OAUTH2_SCOPE_PROPERTY = "scope"; |
436 | + public static final String OAUTH2_PLATFORMS_PROPERTY = "platforms"; | ||
436 | public static final String OAUTH2_USER_INFO_URI_PROPERTY = "user_info_uri"; | 437 | public static final String OAUTH2_USER_INFO_URI_PROPERTY = "user_info_uri"; |
437 | public static final String OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY = "user_name_attribute_name"; | 438 | public static final String OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY = "user_name_attribute_name"; |
438 | public static final String OAUTH2_JWK_SET_URI_PROPERTY = "jwk_set_uri"; | 439 | public static final String OAUTH2_JWK_SET_URI_PROPERTY = "jwk_set_uri"; |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.dao.model.sql; | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import io.micrometer.core.instrument.util.StringUtils; | ||
19 | import lombok.Data; | 20 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
21 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
@@ -27,6 +28,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2BasicMapperConfig; | @@ -27,6 +28,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2BasicMapperConfig; | ||
27 | import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; | 28 | import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
28 | import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; | 29 | import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
29 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | 30 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
31 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
30 | import org.thingsboard.server.common.data.oauth2.TenantNameStrategyType; | 32 | import org.thingsboard.server.common.data.oauth2.TenantNameStrategyType; |
31 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 33 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
32 | import org.thingsboard.server.dao.model.ModelConstants; | 34 | import org.thingsboard.server.dao.model.ModelConstants; |
@@ -38,7 +40,9 @@ import javax.persistence.EnumType; | @@ -38,7 +40,9 @@ import javax.persistence.EnumType; | ||
38 | import javax.persistence.Enumerated; | 40 | import javax.persistence.Enumerated; |
39 | import javax.persistence.Table; | 41 | import javax.persistence.Table; |
40 | import java.util.Arrays; | 42 | import java.util.Arrays; |
43 | +import java.util.Collections; | ||
41 | import java.util.UUID; | 44 | import java.util.UUID; |
45 | +import java.util.stream.Collectors; | ||
42 | 46 | ||
43 | @Data | 47 | @Data |
44 | @EqualsAndHashCode(callSuper = true) | 48 | @EqualsAndHashCode(callSuper = true) |
@@ -59,6 +63,8 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | @@ -59,6 +63,8 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | ||
59 | private String tokenUri; | 63 | private String tokenUri; |
60 | @Column(name = ModelConstants.OAUTH2_SCOPE_PROPERTY) | 64 | @Column(name = ModelConstants.OAUTH2_SCOPE_PROPERTY) |
61 | private String scope; | 65 | private String scope; |
66 | + @Column(name = ModelConstants.OAUTH2_PLATFORMS_PROPERTY) | ||
67 | + private String platforms; | ||
62 | @Column(name = ModelConstants.OAUTH2_USER_INFO_URI_PROPERTY) | 68 | @Column(name = ModelConstants.OAUTH2_USER_INFO_URI_PROPERTY) |
63 | private String userInfoUri; | 69 | private String userInfoUri; |
64 | @Column(name = ModelConstants.OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY) | 70 | @Column(name = ModelConstants.OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY) |
@@ -125,6 +131,7 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | @@ -125,6 +131,7 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | ||
125 | this.authorizationUri = registration.getAuthorizationUri(); | 131 | this.authorizationUri = registration.getAuthorizationUri(); |
126 | this.tokenUri = registration.getAccessTokenUri(); | 132 | this.tokenUri = registration.getAccessTokenUri(); |
127 | this.scope = registration.getScope().stream().reduce((result, element) -> result + "," + element).orElse(""); | 133 | this.scope = registration.getScope().stream().reduce((result, element) -> result + "," + element).orElse(""); |
134 | + this.platforms = registration.getPlatforms() != null ? registration.getPlatforms().stream().map(Enum::name).reduce((result, element) -> result + "," + element).orElse("") : ""; | ||
128 | this.userInfoUri = registration.getUserInfoUri(); | 135 | this.userInfoUri = registration.getUserInfoUri(); |
129 | this.userNameAttributeName = registration.getUserNameAttributeName(); | 136 | this.userNameAttributeName = registration.getUserNameAttributeName(); |
130 | this.jwkSetUri = registration.getJwkSetUri(); | 137 | this.jwkSetUri = registration.getJwkSetUri(); |
@@ -201,6 +208,8 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | @@ -201,6 +208,8 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> | ||
201 | registration.setAuthorizationUri(authorizationUri); | 208 | registration.setAuthorizationUri(authorizationUri); |
202 | registration.setAccessTokenUri(tokenUri); | 209 | registration.setAccessTokenUri(tokenUri); |
203 | registration.setScope(Arrays.asList(scope.split(","))); | 210 | registration.setScope(Arrays.asList(scope.split(","))); |
211 | + registration.setPlatforms(StringUtils.isNotEmpty(platforms) ? Arrays.stream(platforms.split(",")) | ||
212 | + .map(str -> PlatformType.valueOf(str)).collect(Collectors.toList()) : Collections.emptyList()); | ||
204 | registration.setUserInfoUri(userInfoUri); | 213 | registration.setUserInfoUri(userInfoUri); |
205 | registration.setUserNameAttributeName(userNameAttributeName); | 214 | registration.setUserNameAttributeName(userNameAttributeName); |
206 | registration.setJwkSetUri(jwkSetUri); | 215 | registration.setJwkSetUri(jwkSetUri); |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.dao.oauth2; | 16 | package org.thingsboard.server.dao.oauth2; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | 18 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
19 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
19 | import org.thingsboard.server.common.data.oauth2.SchemeType; | 20 | import org.thingsboard.server.common.data.oauth2.SchemeType; |
20 | import org.thingsboard.server.dao.Dao; | 21 | import org.thingsboard.server.dao.Dao; |
21 | 22 | ||
@@ -24,7 +25,7 @@ import java.util.UUID; | @@ -24,7 +25,7 @@ import java.util.UUID; | ||
24 | 25 | ||
25 | public interface OAuth2RegistrationDao extends Dao<OAuth2Registration> { | 26 | public interface OAuth2RegistrationDao extends Dao<OAuth2Registration> { |
26 | 27 | ||
27 | - List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgName(List<SchemeType> domainSchemes, String domainName, String pkgName); | 28 | + List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(List<SchemeType> domainSchemes, String domainName, String pkgName, PlatformType platformType); |
28 | 29 | ||
29 | List<OAuth2Registration> findByOAuth2ParamsId(UUID oauth2ParamsId); | 30 | List<OAuth2Registration> findByOAuth2ParamsId(UUID oauth2ParamsId); |
30 | 31 |
@@ -65,8 +65,8 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se | @@ -65,8 +65,8 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se | ||
65 | private OAuth2MobileDao oauth2MobileDao; | 65 | private OAuth2MobileDao oauth2MobileDao; |
66 | 66 | ||
67 | @Override | 67 | @Override |
68 | - public List<OAuth2ClientInfo> getOAuth2Clients(String domainSchemeStr, String domainName, String pkgName) { | ||
69 | - log.trace("Executing getOAuth2Clients [{}://{}]", domainSchemeStr, domainName); | 68 | + public List<OAuth2ClientInfo> getOAuth2Clients(String domainSchemeStr, String domainName, String pkgName, PlatformType platformType) { |
69 | + log.trace("Executing getOAuth2Clients [{}://{}] pkgName=[{}] platformType=[{}]", domainSchemeStr, domainName, pkgName, platformType); | ||
70 | if (domainSchemeStr == null) { | 70 | if (domainSchemeStr == null) { |
71 | throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); | 71 | throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); |
72 | } | 72 | } |
@@ -77,7 +77,9 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se | @@ -77,7 +77,9 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se | ||
77 | throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); | 77 | throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); |
78 | } | 78 | } |
79 | validateString(domainName, INCORRECT_DOMAIN_NAME + domainName); | 79 | validateString(domainName, INCORRECT_DOMAIN_NAME + domainName); |
80 | - return oauth2RegistrationDao.findEnabledByDomainSchemesDomainNameAndPkgName(Arrays.asList(domainScheme, SchemeType.MIXED), domainName, pkgName).stream() | 80 | + return oauth2RegistrationDao.findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType( |
81 | + Arrays.asList(domainScheme, SchemeType.MIXED), domainName, pkgName, platformType) | ||
82 | + .stream() | ||
81 | .map(OAuth2Utils::toClientInfo) | 83 | .map(OAuth2Utils::toClientInfo) |
82 | .collect(Collectors.toList()); | 84 | .collect(Collectors.toList()); |
83 | } | 85 | } |
@@ -127,6 +127,7 @@ public class OAuth2Utils { | @@ -127,6 +127,7 @@ public class OAuth2Utils { | ||
127 | .authorizationUri(registration.getAuthorizationUri()) | 127 | .authorizationUri(registration.getAuthorizationUri()) |
128 | .accessTokenUri(registration.getAccessTokenUri()) | 128 | .accessTokenUri(registration.getAccessTokenUri()) |
129 | .scope(registration.getScope()) | 129 | .scope(registration.getScope()) |
130 | + .platforms(registration.getPlatforms()) | ||
130 | .userInfoUri(registration.getUserInfoUri()) | 131 | .userInfoUri(registration.getUserInfoUri()) |
131 | .userNameAttributeName(registration.getUserNameAttributeName()) | 132 | .userNameAttributeName(registration.getUserNameAttributeName()) |
132 | .jwkSetUri(registration.getJwkSetUri()) | 133 | .jwkSetUri(registration.getJwkSetUri()) |
@@ -167,6 +168,7 @@ public class OAuth2Utils { | @@ -167,6 +168,7 @@ public class OAuth2Utils { | ||
167 | registration.setAuthorizationUri(registrationInfo.getAuthorizationUri()); | 168 | registration.setAuthorizationUri(registrationInfo.getAuthorizationUri()); |
168 | registration.setAccessTokenUri(registrationInfo.getAccessTokenUri()); | 169 | registration.setAccessTokenUri(registrationInfo.getAccessTokenUri()); |
169 | registration.setScope(registrationInfo.getScope()); | 170 | registration.setScope(registrationInfo.getScope()); |
171 | + registration.setPlatforms(registrationInfo.getPlatforms()); | ||
170 | registration.setUserInfoUri(registrationInfo.getUserInfoUri()); | 172 | registration.setUserInfoUri(registrationInfo.getUserInfoUri()); |
171 | registration.setUserNameAttributeName(registrationInfo.getUserNameAttributeName()); | 173 | registration.setUserNameAttributeName(registrationInfo.getUserNameAttributeName()); |
172 | registration.setJwkSetUri(registrationInfo.getJwkSetUri()); | 174 | registration.setJwkSetUri(registrationInfo.getJwkSetUri()); |
@@ -224,6 +226,7 @@ public class OAuth2Utils { | @@ -224,6 +226,7 @@ public class OAuth2Utils { | ||
224 | .loginButtonLabel(clientRegistrationDto.getLoginButtonLabel()) | 226 | .loginButtonLabel(clientRegistrationDto.getLoginButtonLabel()) |
225 | .loginButtonIcon(clientRegistrationDto.getLoginButtonIcon()) | 227 | .loginButtonIcon(clientRegistrationDto.getLoginButtonIcon()) |
226 | .additionalInfo(clientRegistrationDto.getAdditionalInfo()) | 228 | .additionalInfo(clientRegistrationDto.getAdditionalInfo()) |
229 | + .platforms(Collections.emptyList()) | ||
227 | .build(); | 230 | .build(); |
228 | } | 231 | } |
229 | 232 |
@@ -19,6 +19,7 @@ import lombok.RequiredArgsConstructor; | @@ -19,6 +19,7 @@ import lombok.RequiredArgsConstructor; | ||
19 | import org.springframework.data.repository.CrudRepository; | 19 | import org.springframework.data.repository.CrudRepository; |
20 | import org.springframework.stereotype.Component; | 20 | import org.springframework.stereotype.Component; |
21 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | 21 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
22 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
22 | import org.thingsboard.server.common.data.oauth2.SchemeType; | 23 | import org.thingsboard.server.common.data.oauth2.SchemeType; |
23 | import org.thingsboard.server.dao.DaoUtil; | 24 | import org.thingsboard.server.dao.DaoUtil; |
24 | import org.thingsboard.server.dao.model.sql.OAuth2RegistrationEntity; | 25 | import org.thingsboard.server.dao.model.sql.OAuth2RegistrationEntity; |
@@ -45,8 +46,9 @@ public class JpaOAuth2RegistrationDao extends JpaAbstractDao<OAuth2RegistrationE | @@ -45,8 +46,9 @@ public class JpaOAuth2RegistrationDao extends JpaAbstractDao<OAuth2RegistrationE | ||
45 | } | 46 | } |
46 | 47 | ||
47 | @Override | 48 | @Override |
48 | - public List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgName(List<SchemeType> domainSchemes, String domainName, String pkgName) { | ||
49 | - return DaoUtil.convertDataList(repository.findAllEnabledByDomainSchemesNameAndPkgName(domainSchemes, domainName, pkgName)); | 49 | + public List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(List<SchemeType> domainSchemes, String domainName, String pkgName, PlatformType platformType) { |
50 | + return DaoUtil.convertDataList(repository.findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(domainSchemes, domainName, pkgName, | ||
51 | + platformType != null ? "%" + platformType.name() + "%" : null)); | ||
50 | } | 52 | } |
51 | 53 | ||
52 | @Override | 54 | @Override |
@@ -30,14 +30,15 @@ public interface OAuth2RegistrationRepository extends CrudRepository<OAuth2Regis | @@ -30,14 +30,15 @@ public interface OAuth2RegistrationRepository extends CrudRepository<OAuth2Regis | ||
30 | "FROM OAuth2RegistrationEntity reg " + | 30 | "FROM OAuth2RegistrationEntity reg " + |
31 | "LEFT JOIN OAuth2ParamsEntity params on reg.oauth2ParamsId = params.id " + | 31 | "LEFT JOIN OAuth2ParamsEntity params on reg.oauth2ParamsId = params.id " + |
32 | "LEFT JOIN OAuth2DomainEntity domain on reg.oauth2ParamsId = domain.oauth2ParamsId " + | 32 | "LEFT JOIN OAuth2DomainEntity domain on reg.oauth2ParamsId = domain.oauth2ParamsId " + |
33 | - "LEFT JOIN OAuth2MobileEntity mobile on reg.oauth2ParamsId = mobile.oauth2ParamsId " + | ||
34 | "WHERE params.enabled = true " + | 33 | "WHERE params.enabled = true " + |
35 | "AND domain.domainName = :domainName " + | 34 | "AND domain.domainName = :domainName " + |
36 | "AND domain.domainScheme IN (:domainSchemes) " + | 35 | "AND domain.domainScheme IN (:domainSchemes) " + |
37 | - "AND (:pkgName IS NULL OR mobile.pkgName = :pkgName)") | ||
38 | - List<OAuth2RegistrationEntity> findAllEnabledByDomainSchemesNameAndPkgName(@Param("domainSchemes") List<SchemeType> domainSchemes, | ||
39 | - @Param("domainName") String domainName, | ||
40 | - @Param("pkgName") String pkgName); | 36 | + "AND (:pkgName IS NULL OR EXISTS (SELECT mobile FROM OAuth2MobileEntity mobile WHERE mobile.oauth2ParamsId = reg.oauth2ParamsId AND mobile.pkgName = :pkgName)) " + |
37 | + "AND (:platformFilter IS NULL OR reg.platforms IS NULL OR reg.platforms = '' OR reg.platforms LIKE :platformFilter)") | ||
38 | + List<OAuth2RegistrationEntity> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(@Param("domainSchemes") List<SchemeType> domainSchemes, | ||
39 | + @Param("domainName") String domainName, | ||
40 | + @Param("pkgName") String pkgName, | ||
41 | + @Param("platformFilter") String platformFilter); | ||
41 | 42 | ||
42 | List<OAuth2RegistrationEntity> findByOauth2ParamsId(UUID oauth2ParamsId); | 43 | List<OAuth2RegistrationEntity> findByOauth2ParamsId(UUID oauth2ParamsId); |
43 | 44 |
@@ -391,6 +391,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | @@ -391,6 +391,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | ||
391 | authorization_uri varchar(255), | 391 | authorization_uri varchar(255), |
392 | token_uri varchar(255), | 392 | token_uri varchar(255), |
393 | scope varchar(255), | 393 | scope varchar(255), |
394 | + platforms varchar(255), | ||
394 | user_info_uri varchar(255), | 395 | user_info_uri varchar(255), |
395 | user_name_attribute_name varchar(255), | 396 | user_name_attribute_name varchar(255), |
396 | jwk_set_uri varchar(255), | 397 | jwk_set_uri varchar(255), |
@@ -428,6 +428,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | @@ -428,6 +428,7 @@ CREATE TABLE IF NOT EXISTS oauth2_registration ( | ||
428 | authorization_uri varchar(255), | 428 | authorization_uri varchar(255), |
429 | token_uri varchar(255), | 429 | token_uri varchar(255), |
430 | scope varchar(255), | 430 | scope varchar(255), |
431 | + platforms varchar(255), | ||
431 | user_info_uri varchar(255), | 432 | user_info_uri varchar(255), |
432 | user_name_attribute_name varchar(255), | 433 | user_name_attribute_name varchar(255), |
433 | jwk_set_uri varchar(255), | 434 | jwk_set_uri varchar(255), |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.service; | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
18 | import com.google.common.collect.Lists; | 19 | import com.google.common.collect.Lists; |
19 | import org.junit.After; | 20 | import org.junit.After; |
20 | import org.junit.Assert; | 21 | import org.junit.Assert; |
@@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2MobileInfo; | @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2MobileInfo; | ||
31 | import org.thingsboard.server.common.data.oauth2.OAuth2ParamsInfo; | 32 | import org.thingsboard.server.common.data.oauth2.OAuth2ParamsInfo; |
32 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | 33 | import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
33 | import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; | 34 | import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
35 | +import org.thingsboard.server.common.data.oauth2.PlatformType; | ||
34 | import org.thingsboard.server.common.data.oauth2.SchemeType; | 36 | import org.thingsboard.server.common.data.oauth2.SchemeType; |
35 | import org.thingsboard.server.dao.exception.DataValidationException; | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
36 | import org.thingsboard.server.dao.oauth2.OAuth2Service; | 38 | import org.thingsboard.server.dao.oauth2.OAuth2Service; |
@@ -231,10 +233,10 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -231,10 +233,10 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
231 | registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) | 233 | registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
232 | .collect(Collectors.toList()); | 234 | .collect(Collectors.toList()); |
233 | 235 | ||
234 | - List<OAuth2ClientInfo> nonExistentDomainClients = oAuth2Service.getOAuth2Clients("http", "non-existent-domain", null); | 236 | + List<OAuth2ClientInfo> nonExistentDomainClients = oAuth2Service.getOAuth2Clients("http", "non-existent-domain", null, null); |
235 | Assert.assertTrue(nonExistentDomainClients.isEmpty()); | 237 | Assert.assertTrue(nonExistentDomainClients.isEmpty()); |
236 | 238 | ||
237 | - List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null); | 239 | + List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); |
238 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); | 240 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); |
239 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { | 241 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
240 | Assert.assertTrue( | 242 | Assert.assertTrue( |
@@ -244,10 +246,10 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -244,10 +246,10 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
244 | ); | 246 | ); |
245 | }); | 247 | }); |
246 | 248 | ||
247 | - List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null); | 249 | + List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null); |
248 | Assert.assertTrue(firstDomainHttpsClients.isEmpty()); | 250 | Assert.assertTrue(firstDomainHttpsClients.isEmpty()); |
249 | 251 | ||
250 | - List<OAuth2ClientInfo> fourthDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "fourth-domain", null); | 252 | + List<OAuth2ClientInfo> fourthDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "fourth-domain", null, null); |
251 | Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpClients.size()); | 253 | Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpClients.size()); |
252 | secondGroupClientInfos.forEach(secondGroupClientInfo -> { | 254 | secondGroupClientInfos.forEach(secondGroupClientInfo -> { |
253 | Assert.assertTrue( | 255 | Assert.assertTrue( |
@@ -256,7 +258,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -256,7 +258,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
256 | && clientInfo.getName().equals(secondGroupClientInfo.getName())) | 258 | && clientInfo.getName().equals(secondGroupClientInfo.getName())) |
257 | ); | 259 | ); |
258 | }); | 260 | }); |
259 | - List<OAuth2ClientInfo> fourthDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "fourth-domain", null); | 261 | + List<OAuth2ClientInfo> fourthDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "fourth-domain", null, null); |
260 | Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpsClients.size()); | 262 | Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpsClients.size()); |
261 | secondGroupClientInfos.forEach(secondGroupClientInfo -> { | 263 | secondGroupClientInfos.forEach(secondGroupClientInfo -> { |
262 | Assert.assertTrue( | 264 | Assert.assertTrue( |
@@ -266,7 +268,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -266,7 +268,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
266 | ); | 268 | ); |
267 | }); | 269 | }); |
268 | 270 | ||
269 | - List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null); | 271 | + List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
270 | Assert.assertEquals(firstGroupClientInfos.size() + secondGroupClientInfos.size(), secondDomainHttpClients.size()); | 272 | Assert.assertEquals(firstGroupClientInfos.size() + secondGroupClientInfos.size(), secondDomainHttpClients.size()); |
271 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { | 273 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
272 | Assert.assertTrue( | 274 | Assert.assertTrue( |
@@ -283,7 +285,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -283,7 +285,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
283 | ); | 285 | ); |
284 | }); | 286 | }); |
285 | 287 | ||
286 | - List<OAuth2ClientInfo> secondDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "second-domain", null); | 288 | + List<OAuth2ClientInfo> secondDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "second-domain", null, null); |
287 | Assert.assertEquals(firstGroupClientInfos.size() + thirdGroupClientInfos.size(), secondDomainHttpsClients.size()); | 289 | Assert.assertEquals(firstGroupClientInfos.size() + thirdGroupClientInfos.size(), secondDomainHttpsClients.size()); |
288 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { | 290 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
289 | Assert.assertTrue( | 291 | Assert.assertTrue( |
@@ -331,7 +333,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -331,7 +333,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
331 | registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) | 333 | registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
332 | .collect(Collectors.toList()); | 334 | .collect(Collectors.toList()); |
333 | 335 | ||
334 | - List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null); | 336 | + List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); |
335 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); | 337 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); |
336 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { | 338 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
337 | Assert.assertTrue( | 339 | Assert.assertTrue( |
@@ -341,7 +343,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -341,7 +343,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
341 | ); | 343 | ); |
342 | }); | 344 | }); |
343 | 345 | ||
344 | - List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null); | 346 | + List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null); |
345 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpsClients.size()); | 347 | Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpsClients.size()); |
346 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { | 348 | firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
347 | Assert.assertTrue( | 349 | Assert.assertTrue( |
@@ -381,13 +383,13 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -381,13 +383,13 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
381 | 383 | ||
382 | oAuth2Service.saveOAuth2Info(oAuth2Info); | 384 | oAuth2Service.saveOAuth2Info(oAuth2Info); |
383 | 385 | ||
384 | - List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null); | 386 | + List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
385 | Assert.assertEquals(5, secondDomainHttpClients.size()); | 387 | Assert.assertEquals(5, secondDomainHttpClients.size()); |
386 | 388 | ||
387 | oAuth2Info.setEnabled(false); | 389 | oAuth2Info.setEnabled(false); |
388 | oAuth2Service.saveOAuth2Info(oAuth2Info); | 390 | oAuth2Service.saveOAuth2Info(oAuth2Info); |
389 | 391 | ||
390 | - List<OAuth2ClientInfo> secondDomainHttpDisabledClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null); | 392 | + List<OAuth2ClientInfo> secondDomainHttpDisabledClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
391 | Assert.assertEquals(0, secondDomainHttpDisabledClients.size()); | 393 | Assert.assertEquals(0, secondDomainHttpDisabledClients.size()); |
392 | } | 394 | } |
393 | 395 | ||
@@ -520,7 +522,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -520,7 +522,7 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
520 | OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); | 522 | OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
521 | Assert.assertEquals(oAuth2Info, foundOAuth2Info); | 523 | Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
522 | 524 | ||
523 | - List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1"); | 525 | + List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null); |
524 | Assert.assertEquals(3, firstDomainHttpClients.size()); | 526 | Assert.assertEquals(3, firstDomainHttpClients.size()); |
525 | for (OAuth2ClientInfo clientInfo : firstDomainHttpClients) { | 527 | for (OAuth2ClientInfo clientInfo : firstDomainHttpClients) { |
526 | String[] segments = clientInfo.getUrl().split("/"); | 528 | String[] segments = clientInfo.getUrl().split("/"); |
@@ -536,6 +538,56 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -536,6 +538,56 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
536 | } | 538 | } |
537 | } | 539 | } |
538 | 540 | ||
541 | + @Test | ||
542 | + public void testFindClientsByPackageAndPlatform() { | ||
543 | + OAuth2Info oAuth2Info = new OAuth2Info(true, Lists.newArrayList( | ||
544 | + OAuth2ParamsInfo.builder() | ||
545 | + .domainInfos(Lists.newArrayList( | ||
546 | + OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), | ||
547 | + OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), | ||
548 | + OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() | ||
549 | + )) | ||
550 | + .mobileInfos(Lists.newArrayList( | ||
551 | + OAuth2MobileInfo.builder().pkgName("com.test.pkg1").callbackUrlScheme("testPkg1Callback").build(), | ||
552 | + OAuth2MobileInfo.builder().pkgName("com.test.pkg2").callbackUrlScheme("testPkg2Callback").build() | ||
553 | + )) | ||
554 | + .clientRegistrations(Lists.newArrayList( | ||
555 | + validRegistrationInfo("Google", Arrays.asList(PlatformType.WEB, PlatformType.ANDROID)), | ||
556 | + validRegistrationInfo("Facebook", Arrays.asList(PlatformType.IOS)), | ||
557 | + validRegistrationInfo("GitHub", Collections.emptyList()) | ||
558 | + )) | ||
559 | + .build(), | ||
560 | + OAuth2ParamsInfo.builder() | ||
561 | + .domainInfos(Lists.newArrayList( | ||
562 | + OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), | ||
563 | + OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() | ||
564 | + )) | ||
565 | + .mobileInfos(Collections.emptyList()) | ||
566 | + .clientRegistrations(Lists.newArrayList( | ||
567 | + validRegistrationInfo(), | ||
568 | + validRegistrationInfo() | ||
569 | + )) | ||
570 | + .build() | ||
571 | + )); | ||
572 | + oAuth2Service.saveOAuth2Info(oAuth2Info); | ||
573 | + | ||
574 | + OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); | ||
575 | + Assert.assertEquals(oAuth2Info, foundOAuth2Info); | ||
576 | + | ||
577 | + List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); | ||
578 | + Assert.assertEquals(3, firstDomainHttpClients.size()); | ||
579 | + List<OAuth2ClientInfo> pkg1Clients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null); | ||
580 | + Assert.assertEquals(3, pkg1Clients.size()); | ||
581 | + List<OAuth2ClientInfo> pkg1AndroidClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.ANDROID); | ||
582 | + Assert.assertEquals(2, pkg1AndroidClients.size()); | ||
583 | + Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("Google"))); | ||
584 | + Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("GitHub"))); | ||
585 | + List<OAuth2ClientInfo> pkg1IOSClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.IOS); | ||
586 | + Assert.assertEquals(2, pkg1IOSClients.size()); | ||
587 | + Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("Facebook"))); | ||
588 | + Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("GitHub"))); | ||
589 | + } | ||
590 | + | ||
539 | private OAuth2Info createDefaultOAuth2Info() { | 591 | private OAuth2Info createDefaultOAuth2Info() { |
540 | return new OAuth2Info(true, Lists.newArrayList( | 592 | return new OAuth2Info(true, Lists.newArrayList( |
541 | OAuth2ParamsInfo.builder() | 593 | OAuth2ParamsInfo.builder() |
@@ -567,17 +619,22 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | @@ -567,17 +619,22 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { | ||
567 | } | 619 | } |
568 | 620 | ||
569 | private OAuth2RegistrationInfo validRegistrationInfo() { | 621 | private OAuth2RegistrationInfo validRegistrationInfo() { |
622 | + return validRegistrationInfo(null, Collections.emptyList()); | ||
623 | + } | ||
624 | + | ||
625 | + private OAuth2RegistrationInfo validRegistrationInfo(String label, List<PlatformType> platforms) { | ||
570 | return OAuth2RegistrationInfo.builder() | 626 | return OAuth2RegistrationInfo.builder() |
571 | .clientId(UUID.randomUUID().toString()) | 627 | .clientId(UUID.randomUUID().toString()) |
572 | .clientSecret(UUID.randomUUID().toString()) | 628 | .clientSecret(UUID.randomUUID().toString()) |
573 | .authorizationUri(UUID.randomUUID().toString()) | 629 | .authorizationUri(UUID.randomUUID().toString()) |
574 | .accessTokenUri(UUID.randomUUID().toString()) | 630 | .accessTokenUri(UUID.randomUUID().toString()) |
575 | .scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString())) | 631 | .scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString())) |
632 | + .platforms(platforms == null ? Collections.emptyList() : platforms) | ||
576 | .userInfoUri(UUID.randomUUID().toString()) | 633 | .userInfoUri(UUID.randomUUID().toString()) |
577 | .userNameAttributeName(UUID.randomUUID().toString()) | 634 | .userNameAttributeName(UUID.randomUUID().toString()) |
578 | .jwkSetUri(UUID.randomUUID().toString()) | 635 | .jwkSetUri(UUID.randomUUID().toString()) |
579 | .clientAuthenticationMethod(UUID.randomUUID().toString()) | 636 | .clientAuthenticationMethod(UUID.randomUUID().toString()) |
580 | - .loginButtonLabel(UUID.randomUUID().toString()) | 637 | + .loginButtonLabel(label != null ? label : UUID.randomUUID().toString()) |
581 | .loginButtonIcon(UUID.randomUUID().toString()) | 638 | .loginButtonIcon(UUID.randomUUID().toString()) |
582 | .additionalInfo(mapper.createObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString())) | 639 | .additionalInfo(mapper.createObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString())) |
583 | .mapperConfig( | 640 | .mapperConfig( |
@@ -44,7 +44,7 @@ import { AdminService } from '@core/http/admin.service'; | @@ -44,7 +44,7 @@ import { AdminService } from '@core/http/admin.service'; | ||
44 | import { ActionNotificationShow } from '@core/notification/notification.actions'; | 44 | import { ActionNotificationShow } from '@core/notification/notification.actions'; |
45 | import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; | 45 | import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; |
46 | import { AlertDialogComponent } from '@shared/components/dialog/alert-dialog.component'; | 46 | import { AlertDialogComponent } from '@shared/components/dialog/alert-dialog.component'; |
47 | -import { OAuth2ClientInfo } from '@shared/models/oauth2.models'; | 47 | +import { OAuth2ClientInfo, PlatformType } from '@shared/models/oauth2.models'; |
48 | import { isDefinedAndNotNull, isMobileApp } from '@core/utils'; | 48 | import { isDefinedAndNotNull, isMobileApp } from '@core/utils'; |
49 | 49 | ||
50 | @Injectable({ | 50 | @Injectable({ |
@@ -204,11 +204,8 @@ export class AuthService { | @@ -204,11 +204,8 @@ export class AuthService { | ||
204 | } | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
207 | - public loadOAuth2Clients(pkgName?: string): Observable<Array<OAuth2ClientInfo>> { | ||
208 | - let url = '/api/noauth/oauth2Clients'; | ||
209 | - if (isDefinedAndNotNull(pkgName)) { | ||
210 | - url += `?pkgName=${pkgName}`; | ||
211 | - } | 207 | + public loadOAuth2Clients(): Observable<Array<OAuth2ClientInfo>> { |
208 | + const url = '/api/noauth/oauth2Clients?platform=' + PlatformType.WEB; | ||
212 | return this.http.post<Array<OAuth2ClientInfo>>(url, | 209 | return this.http.post<Array<OAuth2ClientInfo>>(url, |
213 | null, defaultHttpOptions()).pipe( | 210 | null, defaultHttpOptions()).pipe( |
214 | catchError(err => of([])), | 211 | catchError(err => of([])), |
@@ -201,18 +201,27 @@ | @@ -201,18 +201,27 @@ | ||
201 | 201 | ||
202 | <ng-template matExpansionPanelContent> | 202 | <ng-template matExpansionPanelContent> |
203 | <section [formGroupName]="j"> | 203 | <section [formGroupName]="j"> |
204 | - <section formGroupName="additionalInfo" fxLayout="row"> | ||
205 | - <mat-form-field fxFlex class="mat-block"> | ||
206 | - <mat-label translate>admin.oauth2.login-provider</mat-label> | ||
207 | - <mat-select formControlName="providerName"> | ||
208 | - <mat-option *ngFor="let provider of templateProvider" [value]="provider"> | ||
209 | - {{ provider }} | 204 | + <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> |
205 | + <section fxFlex formGroupName="additionalInfo" fxLayout="row"> | ||
206 | + <mat-form-field fxFlex class="mat-block"> | ||
207 | + <mat-label translate>admin.oauth2.login-provider</mat-label> | ||
208 | + <mat-select formControlName="providerName"> | ||
209 | + <mat-option *ngFor="let provider of templateProvider" [value]="provider"> | ||
210 | + {{ provider }} | ||
211 | + </mat-option> | ||
212 | + </mat-select> | ||
213 | + </mat-form-field> | ||
214 | + <div [tb-help]="getHelpLink(registration)" *ngIf="!isCustomProvider(registration)"></div> | ||
215 | + </section> | ||
216 | + <mat-form-field floatLabel="always" fxFlex class="mat-block"> | ||
217 | + <mat-label translate>admin.oauth2.allowed-platforms</mat-label> | ||
218 | + <mat-select formControlName="platforms" multiple placeholder="{{ 'admin.oauth2.all-platforms' | translate }}"> | ||
219 | + <mat-option *ngFor="let platform of platformTypes" [value]="platform"> | ||
220 | + {{ platformTypeTranslations.get(platform) | translate }} | ||
210 | </mat-option> | 221 | </mat-option> |
211 | </mat-select> | 222 | </mat-select> |
212 | </mat-form-field> | 223 | </mat-form-field> |
213 | - <div [tb-help]="getHelpLink(registration)" *ngIf="!isCustomProvider(registration)"></div> | ||
214 | - </section> | ||
215 | - | 224 | + </div> |
216 | <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> | 225 | <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> |
217 | <mat-form-field fxFlex class="mat-block"> | 226 | <mat-form-field fxFlex class="mat-block"> |
218 | <mat-label translate>admin.oauth2.client-id</mat-label> | 227 | <mat-label translate>admin.oauth2.client-id</mat-label> |
@@ -28,7 +28,8 @@ import { | @@ -28,7 +28,8 @@ import { | ||
28 | OAuth2DomainInfo, | 28 | OAuth2DomainInfo, |
29 | OAuth2Info, OAuth2MobileInfo, | 29 | OAuth2Info, OAuth2MobileInfo, |
30 | OAuth2ParamsInfo, | 30 | OAuth2ParamsInfo, |
31 | - OAuth2RegistrationInfo, | 31 | + OAuth2RegistrationInfo, PlatformType, |
32 | + platformTypeTranslations, | ||
32 | TenantNameStrategy | 33 | TenantNameStrategy |
33 | } from '@shared/models/oauth2.models'; | 34 | } from '@shared/models/oauth2.models'; |
34 | import { Store } from '@ngrx/store'; | 35 | import { Store } from '@ngrx/store'; |
@@ -99,6 +100,8 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha | @@ -99,6 +100,8 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha | ||
99 | tenantNameStrategies = Object.keys(TenantNameStrategy); | 100 | tenantNameStrategies = Object.keys(TenantNameStrategy); |
100 | protocols = Object.keys(DomainSchema); | 101 | protocols = Object.keys(DomainSchema); |
101 | domainSchemaTranslations = domainSchemaTranslations; | 102 | domainSchemaTranslations = domainSchemaTranslations; |
103 | + platformTypes = Object.keys(PlatformType); | ||
104 | + platformTypeTranslations = platformTypeTranslations; | ||
102 | 105 | ||
103 | templateProvider = ['Custom']; | 106 | templateProvider = ['Custom']; |
104 | 107 | ||
@@ -293,6 +296,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha | @@ -293,6 +296,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha | ||
293 | additionalInfo: this.fb.group({ | 296 | additionalInfo: this.fb.group({ |
294 | providerName: [additionalInfo?.providerName ? additionalInfo?.providerName : defaultProviderName, Validators.required] | 297 | providerName: [additionalInfo?.providerName ? additionalInfo?.providerName : defaultProviderName, Validators.required] |
295 | }), | 298 | }), |
299 | + platforms: [registration?.platforms ? registration.platforms : []], | ||
296 | loginButtonLabel: [registration?.loginButtonLabel ? registration.loginButtonLabel : null, Validators.required], | 300 | loginButtonLabel: [registration?.loginButtonLabel ? registration.loginButtonLabel : null, Validators.required], |
297 | loginButtonIcon: [registration?.loginButtonIcon ? registration.loginButtonIcon : null], | 301 | loginButtonIcon: [registration?.loginButtonIcon ? registration.loginButtonIcon : null], |
298 | clientId: [registration?.clientId ? registration.clientId : '', Validators.required], | 302 | clientId: [registration?.clientId ? registration.clientId : '', Validators.required], |
@@ -63,6 +63,20 @@ export enum TenantNameStrategy{ | @@ -63,6 +63,20 @@ export enum TenantNameStrategy{ | ||
63 | CUSTOM = 'CUSTOM' | 63 | CUSTOM = 'CUSTOM' |
64 | } | 64 | } |
65 | 65 | ||
66 | +export enum PlatformType { | ||
67 | + WEB = 'WEB', | ||
68 | + ANDROID = 'ANDROID', | ||
69 | + IOS = 'IOS' | ||
70 | +} | ||
71 | + | ||
72 | +export const platformTypeTranslations = new Map<PlatformType, string>( | ||
73 | + [ | ||
74 | + [PlatformType.WEB, 'admin.oauth2.platform-web'], | ||
75 | + [PlatformType.ANDROID, 'admin.oauth2.platform-android'], | ||
76 | + [PlatformType.IOS, 'admin.oauth2.platform-ios'] | ||
77 | + ] | ||
78 | +); | ||
79 | + | ||
66 | export interface OAuth2ClientRegistrationTemplate extends OAuth2RegistrationInfo{ | 80 | export interface OAuth2ClientRegistrationTemplate extends OAuth2RegistrationInfo{ |
67 | comment: string; | 81 | comment: string; |
68 | createdTime: number; | 82 | createdTime: number; |
@@ -80,6 +94,7 @@ export interface OAuth2RegistrationInfo { | @@ -80,6 +94,7 @@ export interface OAuth2RegistrationInfo { | ||
80 | accessTokenUri: string; | 94 | accessTokenUri: string; |
81 | authorizationUri: string; | 95 | authorizationUri: string; |
82 | scope: string[]; | 96 | scope: string[]; |
97 | + platforms: PlatformType[]; | ||
83 | jwkSetUri?: string; | 98 | jwkSetUri?: string; |
84 | userInfoUri: string; | 99 | userInfoUri: string; |
85 | clientAuthenticationMethod: ClientAuthenticationMethod; | 100 | clientAuthenticationMethod: ClientAuthenticationMethod; |
@@ -228,7 +228,12 @@ | @@ -228,7 +228,12 @@ | ||
228 | "mobile-callback-url-scheme": "Callback URL scheme", | 228 | "mobile-callback-url-scheme": "Callback URL scheme", |
229 | "add-mobile-app": "Add application", | 229 | "add-mobile-app": "Add application", |
230 | "delete-mobile-app": "Delete application info", | 230 | "delete-mobile-app": "Delete application info", |
231 | - "providers": "Providers" | 231 | + "providers": "Providers", |
232 | + "platform-web": "Web", | ||
233 | + "platform-android": "Android", | ||
234 | + "platform-ios": "iOS", | ||
235 | + "all-platforms": "All platforms", | ||
236 | + "allowed-platforms": "Allowed platforms" | ||
232 | } | 237 | } |
233 | }, | 238 | }, |
234 | "alarm": { | 239 | "alarm": { |