Commit c7e236499ecbec5eeb4bac1d2b21f3adaadb334c

Authored by vzikratyi
1 parent e841f10b

Added support for multiple domains in OAuth2 config

Showing 38 changed files with 1562 additions and 571 deletions
@@ -14,19 +14,17 @@ @@ -14,19 +14,17 @@
14 -- limitations under the License. 14 -- limitations under the License.
15 -- 15 --
16 16
17 -DROP TABLE IF EXISTS oauth2_client_registration; 17 +DROP TABLE IF EXISTS oauth2_client_registration_info;
18 18
19 -CREATE TABLE IF NOT EXISTS oauth2_client_registration (  
20 - id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY, 19 +CREATE TABLE IF NOT EXISTS oauth2_client_registration_info (
  20 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_info_pkey PRIMARY KEY,
21 enabled boolean, 21 enabled boolean,
22 created_time bigint NOT NULL, 22 created_time bigint NOT NULL,
23 additional_info varchar, 23 additional_info varchar,
24 - domain_name varchar(255),  
25 client_id varchar(255), 24 client_id varchar(255),
26 client_secret varchar(255), 25 client_secret varchar(255),
27 authorization_uri varchar(255), 26 authorization_uri varchar(255),
28 token_uri varchar(255), 27 token_uri varchar(255),
29 - redirect_uri_template varchar(255),  
30 scope varchar(255), 28 scope varchar(255),
31 user_info_uri varchar(255), 29 user_info_uri varchar(255),
32 user_name_attribute_name varchar(255), 30 user_name_attribute_name varchar(255),
@@ -51,6 +49,16 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( @@ -51,6 +49,16 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration (
51 custom_send_token boolean 49 custom_send_token boolean
52 ); 50 );
53 51
  52 +DROP TABLE IF EXISTS oauth2_client_registration;
  53 +
  54 +CREATE TABLE IF NOT EXISTS oauth2_client_registration (
  55 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY,
  56 + created_time bigint NOT NULL,
  57 + domain_name varchar(255),
  58 + domain_scheme varchar(31),
  59 + client_registration_info_id uuid
  60 +);
  61 +
54 DROP TABLE IF EXISTS oauth2_client_registration_template; 62 DROP TABLE IF EXISTS oauth2_client_registration_template;
55 63
56 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( 64 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template (
  1 +/**
  2 + * Copyright © 2016-2020 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.config;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.security.crypto.keygen.Base64StringKeyGenerator;
  21 +import org.springframework.security.crypto.keygen.StringKeyGenerator;
  22 +import org.springframework.security.oauth2.client.registration.ClientRegistration;
  23 +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
  24 +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
  25 +import org.springframework.security.oauth2.core.AuthorizationGrantType;
  26 +import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
  27 +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
  28 +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
  29 +import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
  30 +import org.springframework.security.oauth2.core.oidc.OidcScopes;
  31 +import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
  32 +import org.springframework.security.web.util.UrlUtils;
  33 +import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
  34 +import org.springframework.stereotype.Service;
  35 +import org.springframework.util.Assert;
  36 +import org.springframework.util.CollectionUtils;
  37 +import org.springframework.util.StringUtils;
  38 +import org.springframework.web.util.UriComponents;
  39 +import org.springframework.web.util.UriComponentsBuilder;
  40 +import org.thingsboard.server.dao.oauth2.OAuth2Configuration;
  41 +import org.thingsboard.server.utils.WebUtils;
  42 +
  43 +import javax.servlet.http.HttpServletRequest;
  44 +import java.nio.charset.StandardCharsets;
  45 +import java.security.MessageDigest;
  46 +import java.security.NoSuchAlgorithmException;
  47 +import java.util.Base64;
  48 +import java.util.HashMap;
  49 +import java.util.Map;
  50 +
  51 +@Service
  52 +@Slf4j
  53 +public class CustomOAuth2AuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
  54 + public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization";
  55 + public static final String DEFAULT_LOGIN_PROCESSING_URI = "/login/oauth2/code/";
  56 + private static final String REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId";
  57 + private static final char PATH_DELIMITER = '/';
  58 +
  59 + private final AntPathRequestMatcher authorizationRequestMatcher = new AntPathRequestMatcher(
  60 + DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}");
  61 + private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder());
  62 + private final StringKeyGenerator secureKeyGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder().withoutPadding(), 96);
  63 +
  64 + @Autowired
  65 + private ClientRegistrationRepository clientRegistrationRepository;
  66 +
  67 + @Autowired(required = false)
  68 + private OAuth2Configuration oauth2Configuration;
  69 +
  70 +
  71 + @Override
  72 + public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
  73 + String registrationId = this.resolveRegistrationId(request);
  74 + String redirectUriAction = getAction(request, "login");
  75 + return resolve(request, registrationId, redirectUriAction);
  76 + }
  77 +
  78 + @Override
  79 + public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId) {
  80 + if (registrationId == null) {
  81 + return null;
  82 + }
  83 + String redirectUriAction = getAction(request, "authorize");
  84 + return resolve(request, registrationId, redirectUriAction);
  85 + }
  86 +
  87 + private String getAction(HttpServletRequest request, String defaultAction) {
  88 + String action = request.getParameter("action");
  89 + if (action == null) {
  90 + return defaultAction;
  91 + }
  92 + return action;
  93 + }
  94 +
  95 + private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction) {
  96 + if (registrationId == null) {
  97 + return null;
  98 + }
  99 +
  100 + ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
  101 + if (clientRegistration == null) {
  102 + throw new IllegalArgumentException("Invalid Client Registration with Id: " + registrationId);
  103 + }
  104 +
  105 + Map<String, Object> attributes = new HashMap<>();
  106 + attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
  107 +
  108 + OAuth2AuthorizationRequest.Builder builder;
  109 + if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) {
  110 + builder = OAuth2AuthorizationRequest.authorizationCode();
  111 + Map<String, Object> additionalParameters = new HashMap<>();
  112 + if (!CollectionUtils.isEmpty(clientRegistration.getScopes()) &&
  113 + clientRegistration.getScopes().contains(OidcScopes.OPENID)) {
  114 + // Section 3.1.2.1 Authentication Request - https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
  115 + // scope
  116 + // REQUIRED. OpenID Connect requests MUST contain the "openid" scope value.
  117 + addNonceParameters(attributes, additionalParameters);
  118 + }
  119 + if (ClientAuthenticationMethod.NONE.equals(clientRegistration.getClientAuthenticationMethod())) {
  120 + addPkceParameters(attributes, additionalParameters);
  121 + }
  122 + builder.additionalParameters(additionalParameters);
  123 + } else if (AuthorizationGrantType.IMPLICIT.equals(clientRegistration.getAuthorizationGrantType())) {
  124 + builder = OAuth2AuthorizationRequest.implicit();
  125 + } else {
  126 + throw new IllegalArgumentException("Invalid Authorization Grant Type (" +
  127 + clientRegistration.getAuthorizationGrantType().getValue() +
  128 + ") for Client Registration with Id: " + clientRegistration.getRegistrationId());
  129 + }
  130 +
  131 + String redirectUriStr = expandRedirectUri(request, clientRegistration, redirectUriAction);
  132 +
  133 + return builder
  134 + .clientId(clientRegistration.getClientId())
  135 + .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
  136 + .redirectUri(redirectUriStr)
  137 + .scopes(clientRegistration.getScopes())
  138 + .state(this.stateGenerator.generateKey())
  139 + .attributes(attributes)
  140 + .build();
  141 + }
  142 +
  143 + private String resolveRegistrationId(HttpServletRequest request) {
  144 + if (this.authorizationRequestMatcher.matches(request)) {
  145 + return this.authorizationRequestMatcher
  146 + .matcher(request).getVariables().get(REGISTRATION_ID_URI_VARIABLE_NAME);
  147 + }
  148 + return null;
  149 + }
  150 +
  151 + /**
  152 + * Expands the {@link ClientRegistration#getRedirectUriTemplate()} with following provided variables:<br/>
  153 + * - baseUrl (e.g. https://localhost/app) <br/>
  154 + * - baseScheme (e.g. https) <br/>
  155 + * - baseHost (e.g. localhost) <br/>
  156 + * - basePort (e.g. :8080) <br/>
  157 + * - basePath (e.g. /app) <br/>
  158 + * - registrationId (e.g. google) <br/>
  159 + * - action (e.g. login) <br/>
  160 + * <p/>
  161 + * Null variables are provided as empty strings.
  162 + * <p/>
  163 + * Default redirectUriTemplate is: {@link org.springframework.security.config.oauth2.client}.CommonOAuth2Provider#DEFAULT_REDIRECT_URL
  164 + *
  165 + * @return expanded URI
  166 + */
  167 + private String expandRedirectUri(HttpServletRequest request, ClientRegistration clientRegistration, String action) {
  168 + Map<String, String> uriVariables = new HashMap<>();
  169 + uriVariables.put("registrationId", clientRegistration.getRegistrationId());
  170 +
  171 + UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
  172 + .replacePath(request.getContextPath())
  173 + .replaceQuery(null)
  174 + .fragment(null)
  175 + .build();
  176 + String scheme = uriComponents.getScheme();
  177 + uriVariables.put("baseScheme", scheme == null ? "" : scheme);
  178 + String host = uriComponents.getHost();
  179 + uriVariables.put("baseHost", host == null ? "" : host);
  180 + // following logic is based on HierarchicalUriComponents#toUriString()
  181 + int port = uriComponents.getPort();
  182 + uriVariables.put("basePort", port == -1 ? "" : ":" + port);
  183 + String path = uriComponents.getPath();
  184 + if (StringUtils.hasLength(path)) {
  185 + if (path.charAt(0) != PATH_DELIMITER) {
  186 + path = PATH_DELIMITER + path;
  187 + }
  188 + }
  189 + uriVariables.put("basePath", path == null ? "" : path);
  190 + uriVariables.put("baseUrl", uriComponents.toUriString());
  191 +
  192 + uriVariables.put("action", action == null ? "" : action);
  193 +
  194 + return UriComponentsBuilder.fromUriString(getRedirectUri(request))
  195 + .buildAndExpand(uriVariables)
  196 + .toUriString();
  197 + }
  198 +
  199 + private String getRedirectUri(HttpServletRequest request) {
  200 + String loginProcessingUri = oauth2Configuration != null ? oauth2Configuration.getLoginProcessingUrl() : DEFAULT_LOGIN_PROCESSING_URI;
  201 +
  202 + String scheme = WebUtils.getScheme(request);
  203 + String host = WebUtils.getHost(request);
  204 + String port = WebUtils.getPort(request);
  205 + log.trace("Scheme - {}, host - {}, port - {}.", scheme, host, port);
  206 + String requestHost = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
  207 + return requestHost + loginProcessingUri;
  208 + }
  209 +
  210 + /**
  211 + * Creates nonce and its hash for use in OpenID Connect 1.0 Authentication Requests.
  212 + *
  213 + * @param attributes where the {@link OidcParameterNames#NONCE} is stored for the authentication request
  214 + * @param additionalParameters where the {@link OidcParameterNames#NONCE} hash is added for the authentication request
  215 + *
  216 + * @since 5.2
  217 + * @see <a target="_blank" href="https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest">3.1.2.1. Authentication Request</a>
  218 + */
  219 + private void addNonceParameters(Map<String, Object> attributes, Map<String, Object> additionalParameters) {
  220 + try {
  221 + String nonce = this.secureKeyGenerator.generateKey();
  222 + String nonceHash = createHash(nonce);
  223 + attributes.put(OidcParameterNames.NONCE, nonce);
  224 + additionalParameters.put(OidcParameterNames.NONCE, nonceHash);
  225 + } catch (NoSuchAlgorithmException e) { }
  226 + }
  227 +
  228 + /**
  229 + * Creates and adds additional PKCE parameters for use in the OAuth 2.0 Authorization and Access Token Requests
  230 + *
  231 + * @param attributes where {@link PkceParameterNames#CODE_VERIFIER} is stored for the token request
  232 + * @param additionalParameters where {@link PkceParameterNames#CODE_CHALLENGE} and, usually,
  233 + * {@link PkceParameterNames#CODE_CHALLENGE_METHOD} are added to be used in the authorization request.
  234 + *
  235 + * @since 5.2
  236 + * @see <a target="_blank" href="https://tools.ietf.org/html/rfc7636#section-1.1">1.1. Protocol Flow</a>
  237 + * @see <a target="_blank" href="https://tools.ietf.org/html/rfc7636#section-4.1">4.1. Client Creates a Code Verifier</a>
  238 + * @see <a target="_blank" href="https://tools.ietf.org/html/rfc7636#section-4.2">4.2. Client Creates the Code Challenge</a>
  239 + */
  240 + private void addPkceParameters(Map<String, Object> attributes, Map<String, Object> additionalParameters) {
  241 + String codeVerifier = this.secureKeyGenerator.generateKey();
  242 + attributes.put(PkceParameterNames.CODE_VERIFIER, codeVerifier);
  243 + try {
  244 + String codeChallenge = createHash(codeVerifier);
  245 + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, codeChallenge);
  246 + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256");
  247 + } catch (NoSuchAlgorithmException e) {
  248 + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, codeVerifier);
  249 + }
  250 + }
  251 +
  252 + private static String createHash(String value) throws NoSuchAlgorithmException {
  253 + MessageDigest md = MessageDigest.getInstance("SHA-256");
  254 + byte[] digest = md.digest(value.getBytes(StandardCharsets.US_ASCII));
  255 + return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
  256 + }
  257 +}
@@ -32,6 +32,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe @@ -32,6 +32,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
32 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 32 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
33 import org.springframework.security.config.http.SessionCreationPolicy; 33 import org.springframework.security.config.http.SessionCreationPolicy;
34 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 34 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  35 +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
35 import org.springframework.security.web.authentication.AuthenticationFailureHandler; 36 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
36 import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 37 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
37 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 38 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@@ -175,6 +176,9 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt @@ -175,6 +176,9 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
175 web.ignoring().antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**"); 176 web.ignoring().antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**");
176 } 177 }
177 178
  179 + @Autowired
  180 + private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver;
  181 +
178 @Override 182 @Override
179 protected void configure(HttpSecurity http) throws Exception { 183 protected void configure(HttpSecurity http) throws Exception {
180 http.headers().cacheControl().and().frameOptions().disable() 184 http.headers().cacheControl().and().frameOptions().disable()
@@ -209,6 +213,8 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt @@ -209,6 +213,8 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
209 .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class); 213 .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class);
210 if (oauth2Configuration != null) { 214 if (oauth2Configuration != null) {
211 http.oauth2Login() 215 http.oauth2Login()
  216 + .authorizationEndpoint().authorizationRequestResolver(oAuth2AuthorizationRequestResolver)
  217 + .and()
212 .loginPage("/oauth2Login") 218 .loginPage("/oauth2Login")
213 .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl()) 219 .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
214 .successHandler(oauth2AuthenticationSuccessHandler) 220 .successHandler(oauth2AuthenticationSuccessHandler)
@@ -373,7 +373,7 @@ public abstract class BaseController { @@ -373,7 +373,7 @@ public abstract class BaseController {
373 case WIDGET_TYPE: 373 case WIDGET_TYPE:
374 checkWidgetTypeId(new WidgetTypeId(entityId.getId()), operation); 374 checkWidgetTypeId(new WidgetTypeId(entityId.getId()), operation);
375 return; 375 return;
376 - case OAUTH2_CLIENT_REGISTRATION: 376 + case OAUTH2_CLIENT_REGISTRATION_INFO:
377 case OAUTH2_CLIENT_REGISTRATION_TEMPLATE: 377 case OAUTH2_CLIENT_REGISTRATION_TEMPLATE:
378 return; 378 return;
379 default: 379 default:
@@ -19,13 +19,10 @@ import lombok.extern.slf4j.Slf4j; @@ -19,13 +19,10 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.http.HttpStatus; 19 import org.springframework.http.HttpStatus;
20 import org.springframework.security.access.prepost.PreAuthorize; 20 import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.web.bind.annotation.*; 21 import org.springframework.web.bind.annotation.*;
22 -import org.thingsboard.server.common.data.EntityType;  
23 -import org.thingsboard.server.common.data.audit.ActionType;  
24 import org.thingsboard.server.common.data.exception.ThingsboardException; 22 import org.thingsboard.server.common.data.exception.ThingsboardException;
25 -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;  
26 import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; 23 import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
27 -import org.thingsboard.server.common.data.oauth2.OAuth2ClientsDomainParams;  
28 import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams; 24 import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams;
  25 +import org.thingsboard.server.common.data.oauth2.SchemeType;
29 import org.thingsboard.server.queue.util.TbCoreComponent; 26 import org.thingsboard.server.queue.util.TbCoreComponent;
30 27
31 import javax.servlet.http.HttpServletRequest; 28 import javax.servlet.http.HttpServletRequest;
@@ -36,14 +33,11 @@ import java.util.List; @@ -36,14 +33,11 @@ import java.util.List;
36 @RequestMapping("/api") 33 @RequestMapping("/api")
37 @Slf4j 34 @Slf4j
38 public class OAuth2Controller extends BaseController { 35 public class OAuth2Controller extends BaseController {
39 - private static final String CLIENT_REGISTRATION_ID = "clientRegistrationId";  
40 - private static final String DOMAIN = "domain";  
41 -  
42 @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) 36 @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST)
43 @ResponseBody 37 @ResponseBody
44 public List<OAuth2ClientInfo> getOAuth2Clients(HttpServletRequest request) throws ThingsboardException { 38 public List<OAuth2ClientInfo> getOAuth2Clients(HttpServletRequest request) throws ThingsboardException {
45 try { 39 try {
46 - return oAuth2Service.getOAuth2Clients(request.getServerName()); 40 + return oAuth2Service.getOAuth2Clients(request.getScheme(), request.getServerName());
47 } catch (Exception e) { 41 } catch (Exception e) {
48 throw handleException(e); 42 throw handleException(e);
49 } 43 }
@@ -65,56 +59,9 @@ public class OAuth2Controller extends BaseController { @@ -65,56 +59,9 @@ public class OAuth2Controller extends BaseController {
65 @ResponseStatus(value = HttpStatus.OK) 59 @ResponseStatus(value = HttpStatus.OK)
66 public OAuth2ClientsParams saveOAuth2Params(@RequestBody OAuth2ClientsParams oauth2Params) throws ThingsboardException { 60 public OAuth2ClientsParams saveOAuth2Params(@RequestBody OAuth2ClientsParams oauth2Params) throws ThingsboardException {
67 try { 61 try {
68 - return oAuth2Service.saveOAuth2Params(oauth2Params);  
69 - } catch (Exception e) {  
70 - throw handleException(e);  
71 - }  
72 - }  
73 -  
74 - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")  
75 - @RequestMapping(value = "/oauth2/config/{clientRegistrationId}", method = RequestMethod.DELETE)  
76 - @ResponseStatus(value = HttpStatus.OK)  
77 - public void deleteClientRegistration(@PathVariable(CLIENT_REGISTRATION_ID) String strClientRegistrationId) throws ThingsboardException {  
78 - checkParameter(CLIENT_REGISTRATION_ID, strClientRegistrationId);  
79 - try {  
80 - OAuth2ClientRegistrationId clientRegistrationId = new OAuth2ClientRegistrationId(toUUID(strClientRegistrationId));  
81 - oAuth2Service.deleteClientRegistrationById(clientRegistrationId);  
82 -  
83 - logEntityAction(clientRegistrationId,  
84 - null,  
85 - null,  
86 - ActionType.DELETED, null, strClientRegistrationId);  
87 -  
88 - } catch (Exception e) {  
89 -  
90 - logEntityAction(emptyId(EntityType.OAUTH2_CLIENT_REGISTRATION),  
91 - null,  
92 - null,  
93 - ActionType.DELETED, e, strClientRegistrationId);  
94 -  
95 - throw handleException(e);  
96 - }  
97 - }  
98 -  
99 -  
100 - @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")  
101 - @RequestMapping(value = "/oauth2/config/domain/{domain}", method = RequestMethod.DELETE)  
102 - @ResponseStatus(value = HttpStatus.OK)  
103 - public void deleteClientRegistrationForDomain(@PathVariable(DOMAIN) String domain) throws ThingsboardException {  
104 - checkParameter(DOMAIN, domain);  
105 - try {  
106 - oAuth2Service.deleteClientRegistrationsByDomain(domain);  
107 -  
108 - logEntityAction(emptyId(EntityType.OAUTH2_CLIENT_REGISTRATION), null,  
109 - null,  
110 - ActionType.DELETED, null, domain);  
111 - 62 + oAuth2Service.saveOAuth2Params(oauth2Params);
  63 + return oAuth2Service.findOAuth2Params();
112 } catch (Exception e) { 64 } catch (Exception e) {
113 - logEntityAction(emptyId(EntityType.OAUTH2_CLIENT_REGISTRATION),  
114 - null,  
115 - null,  
116 - ActionType.DELETED, e, domain);  
117 -  
118 throw handleException(e); 65 throw handleException(e);
119 } 66 }
120 } 67 }
@@ -22,7 +22,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; @@ -22,7 +22,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
22 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; 22 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
23 import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; 23 import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
24 import org.springframework.stereotype.Component; 24 import org.springframework.stereotype.Component;
25 -import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; 25 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
26 import org.thingsboard.server.dao.oauth2.OAuth2Service; 26 import org.thingsboard.server.dao.oauth2.OAuth2Service;
27 import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository; 27 import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
28 import org.thingsboard.server.service.security.model.SecurityUser; 28 import org.thingsboard.server.service.security.model.SecurityUser;
@@ -68,7 +68,7 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS @@ -68,7 +68,7 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS
68 try { 68 try {
69 OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication; 69 OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
70 70
71 - OAuth2ClientRegistration clientRegistration = oAuth2Service.findClientRegistration(UUID.fromString(token.getAuthorizedClientRegistrationId())); 71 + OAuth2ClientRegistrationInfo clientRegistration = oAuth2Service.findClientRegistrationInfo(UUID.fromString(token.getAuthorizedClientRegistrationId()));
72 OAuth2AuthorizedClient oAuth2AuthorizedClient = oAuth2AuthorizedClientService.loadAuthorizedClient( 72 OAuth2AuthorizedClient oAuth2AuthorizedClient = oAuth2AuthorizedClientService.loadAuthorizedClient(
73 token.getAuthorizedClientRegistrationId(), 73 token.getAuthorizedClientRegistrationId(),
74 token.getPrincipal().getName()); 74 token.getPrincipal().getName());
@@ -32,7 +32,7 @@ public enum Resource { @@ -32,7 +32,7 @@ public enum Resource {
32 USER(EntityType.USER), 32 USER(EntityType.USER),
33 WIDGETS_BUNDLE(EntityType.WIDGETS_BUNDLE), 33 WIDGETS_BUNDLE(EntityType.WIDGETS_BUNDLE),
34 WIDGET_TYPE(EntityType.WIDGET_TYPE), 34 WIDGET_TYPE(EntityType.WIDGET_TYPE),
35 - OAUTH2_CONFIGURATION(EntityType.OAUTH2_CLIENT_REGISTRATION), 35 + OAUTH2_CONFIGURATION_INFO(EntityType.OAUTH2_CLIENT_REGISTRATION_INFO),
36 OAUTH2_CONFIGURATION_TEMPLATE(EntityType.OAUTH2_CLIENT_REGISTRATION_TEMPLATE), 36 OAUTH2_CONFIGURATION_TEMPLATE(EntityType.OAUTH2_CLIENT_REGISTRATION_TEMPLATE),
37 ; 37 ;
38 38
@@ -35,7 +35,7 @@ public class SysAdminPermissions extends AbstractPermissions { @@ -35,7 +35,7 @@ public class SysAdminPermissions extends AbstractPermissions {
35 put(Resource.USER, userPermissionChecker); 35 put(Resource.USER, userPermissionChecker);
36 put(Resource.WIDGETS_BUNDLE, systemEntityPermissionChecker); 36 put(Resource.WIDGETS_BUNDLE, systemEntityPermissionChecker);
37 put(Resource.WIDGET_TYPE, systemEntityPermissionChecker); 37 put(Resource.WIDGET_TYPE, systemEntityPermissionChecker);
38 - put(Resource.OAUTH2_CONFIGURATION, PermissionChecker.allowAllPermissionChecker); 38 + put(Resource.OAUTH2_CONFIGURATION_INFO, PermissionChecker.allowAllPermissionChecker);
39 put(Resource.OAUTH2_CONFIGURATION_TEMPLATE, PermissionChecker.allowAllPermissionChecker); 39 put(Resource.OAUTH2_CONFIGURATION_TEMPLATE, PermissionChecker.allowAllPermissionChecker);
40 } 40 }
41 41
  1 +/**
  2 + * Copyright © 2016-2020 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.utils;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.apache.commons.lang.StringUtils;
  20 +
  21 +import javax.servlet.http.HttpServletRequest;
  22 +
  23 +@Slf4j
  24 +public class WebUtils {
  25 + private static final String X_FORWARDED_HOST_HEADER_KEY = "x-forwarded-host";
  26 + private static final String X_FORWARDED_PORT_HEADER_KEY = "x-forwarded-port";
  27 + private static final String X_FORWARDED_PROTO_HEADER_KEY = "x-forwarded-proto";
  28 +
  29 + public static String getHost(HttpServletRequest request) {
  30 + String forwardedHost = request.getHeader(X_FORWARDED_HOST_HEADER_KEY);
  31 + log.trace("Forwarded host - {}.", forwardedHost);
  32 + if (!StringUtils.isEmpty(forwardedHost)) {
  33 + if (forwardedHost.contains(":")) {
  34 + return forwardedHost.substring(0, forwardedHost.indexOf(":"));
  35 + } else {
  36 + return forwardedHost;
  37 + }
  38 + } else {
  39 + return request.getServerName();
  40 + }
  41 + }
  42 +
  43 + public static String getScheme(HttpServletRequest request) {
  44 + String forwardedProto = request.getHeader(X_FORWARDED_PROTO_HEADER_KEY);
  45 + log.trace("Forwarded proto - {}.", forwardedProto);
  46 + if (!StringUtils.isEmpty(forwardedProto)) {
  47 + return forwardedProto;
  48 + } else {
  49 + return request.getServerName();
  50 + }
  51 + }
  52 +
  53 + public static String getPort(HttpServletRequest request) {
  54 + String forwardedPort = request.getHeader(X_FORWARDED_PORT_HEADER_KEY);
  55 + log.trace("Forwarded port - {}.", forwardedPort);
  56 + if (!StringUtils.isEmpty(forwardedPort)) {
  57 + return forwardedPort;
  58 + }
  59 + String forwardedHost = request.getHeader(X_FORWARDED_HOST_HEADER_KEY);
  60 + if (!StringUtils.isEmpty(forwardedHost)) {
  61 + if (forwardedHost.contains(":")) {
  62 + return forwardedHost.substring(forwardedHost.indexOf(":"));
  63 + } else {
  64 + return "HTTP".equals(getScheme(request).toUpperCase()) ?
  65 + "80" : "443";
  66 + }
  67 + }
  68 + return Integer.toString(request.getServerPort());
  69 + }
  70 +}
@@ -15,26 +15,21 @@ @@ -15,26 +15,21 @@
15 */ 15 */
16 package org.thingsboard.server.dao.oauth2; 16 package org.thingsboard.server.dao.oauth2;
17 17
18 -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;  
19 import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; 18 import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
20 -import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; 19 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
21 import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams; 20 import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams;
22 21
23 import java.util.List; 22 import java.util.List;
24 import java.util.UUID; 23 import java.util.UUID;
25 24
26 public interface OAuth2Service { 25 public interface OAuth2Service {
27 - List<OAuth2ClientInfo> getOAuth2Clients(String domainName); 26 + List<OAuth2ClientInfo> getOAuth2Clients(String domainScheme, String domainName);
28 27
29 - OAuth2ClientsParams saveOAuth2Params(OAuth2ClientsParams oauth2Params); 28 + void saveOAuth2Params(OAuth2ClientsParams oauth2Params);
30 29
31 OAuth2ClientsParams findOAuth2Params(); 30 OAuth2ClientsParams findOAuth2Params();
32 31
33 - OAuth2ClientRegistration findClientRegistration(UUID id); 32 + OAuth2ClientRegistrationInfo findClientRegistrationInfo(UUID id);
34 33
35 - List<OAuth2ClientRegistration> findAllClientRegistrations();  
36 -  
37 - void deleteClientRegistrationById(OAuth2ClientRegistrationId id);  
38 -  
39 - void deleteClientRegistrationsByDomain(String domain); 34 + List<OAuth2ClientRegistrationInfo> findAllClientRegistrationInfos();
40 } 35 }
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
19 * @author Andrew Shvayka 19 * @author Andrew Shvayka
20 */ 20 */
21 public enum EntityType { 21 public enum EntityType {
22 - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, OAUTH2_CLIENT_REGISTRATION, OAUTH2_CLIENT_REGISTRATION_TEMPLATE 22 + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, OAUTH2_CLIENT_REGISTRATION, OAUTH2_CLIENT_REGISTRATION_INFO, OAUTH2_CLIENT_REGISTRATION_TEMPLATE
23 } 23 }
@@ -62,8 +62,8 @@ public class EntityIdFactory { @@ -62,8 +62,8 @@ public class EntityIdFactory {
62 return new WidgetsBundleId(uuid); 62 return new WidgetsBundleId(uuid);
63 case WIDGET_TYPE: 63 case WIDGET_TYPE:
64 return new WidgetTypeId(uuid); 64 return new WidgetTypeId(uuid);
65 - case OAUTH2_CLIENT_REGISTRATION:  
66 - return new OAuth2ClientRegistrationId(uuid); 65 + case OAUTH2_CLIENT_REGISTRATION_INFO:
  66 + return new OAuth2ClientRegistrationInfoId(uuid);
67 case OAUTH2_CLIENT_REGISTRATION_TEMPLATE: 67 case OAUTH2_CLIENT_REGISTRATION_TEMPLATE:
68 return new OAuth2ClientRegistrationTemplateId(uuid); 68 return new OAuth2ClientRegistrationTemplateId(uuid);
69 } 69 }
  1 +/**
  2 + * Copyright © 2016-2020 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.id;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import org.thingsboard.server.common.data.EntityType;
  21 +
  22 +import java.util.UUID;
  23 +
  24 +public class OAuth2ClientRegistrationInfoId extends UUIDBased implements EntityId {
  25 +
  26 + @JsonCreator
  27 + public OAuth2ClientRegistrationInfoId(@JsonProperty("id") UUID id) {
  28 + super(id);
  29 + }
  30 +
  31 + public static OAuth2ClientRegistrationInfoId fromString(String clientRegistrationInfoId) {
  32 + return new OAuth2ClientRegistrationInfoId(UUID.fromString(clientRegistrationInfoId));
  33 + }
  34 +
  35 + @Override
  36 + public EntityType getEntityType() {
  37 + return EntityType.OAUTH2_CLIENT_REGISTRATION_INFO;
  38 + }
  39 +}
@@ -15,11 +15,9 @@ @@ -15,11 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.oauth2; 16 package org.thingsboard.server.common.data.oauth2;
17 17
18 -import com.fasterxml.jackson.annotation.JsonProperty;  
19 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
20 import lombok.*; 19 import lombok.*;
21 -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;  
22 -import org.thingsboard.server.common.data.id.TenantId; 20 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
23 21
24 import java.util.List; 22 import java.util.List;
25 23
@@ -30,8 +28,6 @@ import java.util.List; @@ -30,8 +28,6 @@ import java.util.List;
30 @AllArgsConstructor 28 @AllArgsConstructor
31 @Builder 29 @Builder
32 public class ClientRegistrationDto { 30 public class ClientRegistrationDto {
33 - private OAuth2ClientRegistrationId id;  
34 - private long createdTime;  
35 private OAuth2MapperConfig mapperConfig; 31 private OAuth2MapperConfig mapperConfig;
36 private String clientId; 32 private String clientId;
37 private String clientSecret; 33 private String clientSecret;
common/data/src/main/java/org/thingsboard/server/common/data/oauth2/DomainInfo.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/oauth2/ExtendedOAuth2ClientRegistration.java
@@ -17,12 +17,13 @@ package org.thingsboard.server.common.data.oauth2; @@ -17,12 +17,13 @@ package org.thingsboard.server.common.data.oauth2;
17 17
18 import lombok.*; 18 import lombok.*;
19 19
  20 +@EqualsAndHashCode
20 @Data 21 @Data
21 @ToString 22 @ToString
22 -@Builder(toBuilder = true)  
23 @NoArgsConstructor 23 @NoArgsConstructor
24 @AllArgsConstructor 24 @AllArgsConstructor
25 -public class ExtendedOAuth2ClientRegistration {  
26 - private String redirectUriTemplate;  
27 - private OAuth2ClientRegistration clientRegistration; 25 +@Builder
  26 +public class DomainInfo {
  27 + private SchemeType scheme;
  28 + private String name;
28 } 29 }
  1 +/**
  2 + * Copyright © 2016-2020 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 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@Data
  23 +public class ExtendedOAuth2ClientRegistrationInfo extends OAuth2ClientRegistrationInfo {
  24 +
  25 + private String domainName;
  26 + private SchemeType domainScheme;
  27 +
  28 + public ExtendedOAuth2ClientRegistrationInfo() {
  29 + super();
  30 + }
  31 +
  32 + public ExtendedOAuth2ClientRegistrationInfo(OAuth2ClientRegistrationInfo oAuth2ClientRegistrationInfo,
  33 + SchemeType domainScheme,
  34 + String domainName) {
  35 + super(oAuth2ClientRegistrationInfo);
  36 + this.domainScheme = domainScheme;
  37 + this.domainName = domainName;
  38 + }
  39 +}
@@ -15,68 +15,28 @@ @@ -15,68 +15,28 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.oauth2; 16 package org.thingsboard.server.common.data.oauth2;
17 17
18 -import com.fasterxml.jackson.annotation.JsonProperty;  
19 import lombok.Data; 18 import lombok.Data;
20 import lombok.EqualsAndHashCode; 19 import lombok.EqualsAndHashCode;
21 import lombok.NoArgsConstructor; 20 import lombok.NoArgsConstructor;
22 import lombok.ToString; 21 import lombok.ToString;
23 -import org.thingsboard.server.common.data.HasName;  
24 -import org.thingsboard.server.common.data.HasTenantId;  
25 -import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; 22 +import org.thingsboard.server.common.data.BaseData;
26 import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId; 23 import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;
27 -import org.thingsboard.server.common.data.id.TenantId;  
28 -  
29 -import java.util.List; 24 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
30 25
31 @EqualsAndHashCode(callSuper = true) 26 @EqualsAndHashCode(callSuper = true)
32 @Data 27 @Data
33 -@ToString(exclude = {"clientSecret"}) 28 +@ToString
34 @NoArgsConstructor 29 @NoArgsConstructor
35 -public class OAuth2ClientRegistration extends SearchTextBasedWithAdditionalInfo<OAuth2ClientRegistrationId> implements HasName { 30 +public class OAuth2ClientRegistration extends BaseData<OAuth2ClientRegistrationId> {
36 31
37 - private boolean enabled; 32 + private OAuth2ClientRegistrationInfoId clientRegistrationId;
38 private String domainName; 33 private String domainName;
39 - private String redirectUriTemplate;  
40 - private OAuth2MapperConfig mapperConfig;  
41 - private String clientId;  
42 - private String clientSecret;  
43 - private String authorizationUri;  
44 - private String accessTokenUri;  
45 - private List<String> scope;  
46 - private String userInfoUri;  
47 - private String userNameAttributeName;  
48 - private String jwkSetUri;  
49 - private String clientAuthenticationMethod;  
50 - private String loginButtonLabel;  
51 - private String loginButtonIcon; 34 + private SchemeType domainScheme;
52 35
53 public OAuth2ClientRegistration(OAuth2ClientRegistration clientRegistration) { 36 public OAuth2ClientRegistration(OAuth2ClientRegistration clientRegistration) {
54 super(clientRegistration); 37 super(clientRegistration);
55 - this.enabled = clientRegistration.enabled; 38 + this.clientRegistrationId = clientRegistration.clientRegistrationId;
56 this.domainName = clientRegistration.domainName; 39 this.domainName = clientRegistration.domainName;
57 - this.redirectUriTemplate = clientRegistration.redirectUriTemplate;  
58 - this.mapperConfig = clientRegistration.mapperConfig;  
59 - this.clientId = clientRegistration.clientId;  
60 - this.clientSecret = clientRegistration.clientSecret;  
61 - this.authorizationUri = clientRegistration.authorizationUri;  
62 - this.accessTokenUri = clientRegistration.accessTokenUri;  
63 - this.scope = clientRegistration.scope;  
64 - this.userInfoUri = clientRegistration.userInfoUri;  
65 - this.userNameAttributeName = clientRegistration.userNameAttributeName;  
66 - this.jwkSetUri = clientRegistration.jwkSetUri;  
67 - this.clientAuthenticationMethod = clientRegistration.clientAuthenticationMethod;  
68 - this.loginButtonLabel = clientRegistration.loginButtonLabel;  
69 - this.loginButtonIcon = clientRegistration.loginButtonIcon;  
70 - }  
71 -  
72 - @Override  
73 - @JsonProperty(access = JsonProperty.Access.READ_ONLY)  
74 - public String getName() {  
75 - return loginButtonLabel;  
76 - }  
77 -  
78 - @Override  
79 - public String getSearchText() {  
80 - return getName(); 40 + this.domainScheme = clientRegistration.domainScheme;
81 } 41 }
82 } 42 }
  1 +/**
  2 + * Copyright © 2016-2020 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 +import com.fasterxml.jackson.annotation.JsonProperty;
  19 +import lombok.Data;
  20 +import lombok.EqualsAndHashCode;
  21 +import lombok.NoArgsConstructor;
  22 +import lombok.ToString;
  23 +import org.thingsboard.server.common.data.HasName;
  24 +import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
  25 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
  26 +
  27 +import java.util.List;
  28 +
  29 +@EqualsAndHashCode(callSuper = true)
  30 +@Data
  31 +@ToString(exclude = {"clientSecret"})
  32 +@NoArgsConstructor
  33 +public class OAuth2ClientRegistrationInfo extends SearchTextBasedWithAdditionalInfo<OAuth2ClientRegistrationInfoId> implements HasName {
  34 +
  35 + private boolean enabled;
  36 + private OAuth2MapperConfig mapperConfig;
  37 + private String clientId;
  38 + private String clientSecret;
  39 + private String authorizationUri;
  40 + private String accessTokenUri;
  41 + private List<String> scope;
  42 + private String userInfoUri;
  43 + private String userNameAttributeName;
  44 + private String jwkSetUri;
  45 + private String clientAuthenticationMethod;
  46 + private String loginButtonLabel;
  47 + private String loginButtonIcon;
  48 +
  49 + public OAuth2ClientRegistrationInfo(OAuth2ClientRegistrationInfo clientRegistration) {
  50 + super(clientRegistration);
  51 + this.enabled = clientRegistration.enabled;
  52 + this.mapperConfig = clientRegistration.mapperConfig;
  53 + this.clientId = clientRegistration.clientId;
  54 + this.clientSecret = clientRegistration.clientSecret;
  55 + this.authorizationUri = clientRegistration.authorizationUri;
  56 + this.accessTokenUri = clientRegistration.accessTokenUri;
  57 + this.scope = clientRegistration.scope;
  58 + this.userInfoUri = clientRegistration.userInfoUri;
  59 + this.userNameAttributeName = clientRegistration.userNameAttributeName;
  60 + this.jwkSetUri = clientRegistration.jwkSetUri;
  61 + this.clientAuthenticationMethod = clientRegistration.clientAuthenticationMethod;
  62 + this.loginButtonLabel = clientRegistration.loginButtonLabel;
  63 + this.loginButtonIcon = clientRegistration.loginButtonIcon;
  64 + }
  65 +
  66 + @Override
  67 + @JsonProperty(access = JsonProperty.Access.READ_ONLY)
  68 + public String getName() {
  69 + return loginButtonLabel;
  70 + }
  71 +
  72 + @Override
  73 + public String getSearchText() {
  74 + return getName();
  75 + }
  76 +}
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.oauth2; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.oauth2;
18 import lombok.*; 18 import lombok.*;
19 19
20 import java.util.List; 20 import java.util.List;
  21 +import java.util.Set;
21 22
22 @EqualsAndHashCode 23 @EqualsAndHashCode
23 @Data 24 @Data
@@ -26,7 +27,6 @@ import java.util.List; @@ -26,7 +27,6 @@ import java.util.List;
26 @NoArgsConstructor 27 @NoArgsConstructor
27 @AllArgsConstructor 28 @AllArgsConstructor
28 public class OAuth2ClientsDomainParams { 29 public class OAuth2ClientsDomainParams {
29 - private String domainName;  
30 - private String redirectUriTemplate;  
31 - private List<ClientRegistrationDto> clientRegistrations; 30 + private Set<DomainInfo> domainInfos;
  31 + private Set<ClientRegistrationDto> clientRegistrations;
32 } 32 }
@@ -16,11 +16,7 @@ @@ -16,11 +16,7 @@
16 package org.thingsboard.server.common.data.oauth2; 16 package org.thingsboard.server.common.data.oauth2;
17 17
18 import lombok.*; 18 import lombok.*;
19 -import org.thingsboard.server.common.data.id.TenantId;  
20 -  
21 -import java.util.Collection;  
22 -import java.util.List;  
23 -import java.util.Objects; 19 +import java.util.Set;
24 20
25 @EqualsAndHashCode 21 @EqualsAndHashCode
26 @Data 22 @Data
@@ -30,5 +26,5 @@ import java.util.Objects; @@ -30,5 +26,5 @@ import java.util.Objects;
30 @AllArgsConstructor 26 @AllArgsConstructor
31 public class OAuth2ClientsParams { 27 public class OAuth2ClientsParams {
32 private boolean enabled; 28 private boolean enabled;
33 - private List<OAuth2ClientsDomainParams> oAuth2DomainDtos; 29 + private Set<OAuth2ClientsDomainParams> oAuth2DomainDtos;
34 } 30 }
  1 +/**
  2 + * Copyright © 2016-2020 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 SchemeType {
  19 + HTTP, HTTPS, MIXED;
  20 +}
@@ -358,11 +358,15 @@ public class ModelConstants { @@ -358,11 +358,15 @@ public class ModelConstants {
358 * OAuth2 client registration constants. 358 * OAuth2 client registration constants.
359 */ 359 */
360 public static final String OAUTH2_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; 360 public static final String OAUTH2_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
361 - public static final String OAUTH2_ENABLED_PROPERTY = "enabled"; 361 + public static final String OAUTH2_CLIENT_REGISTRATION_INFO_COLUMN_FAMILY_NAME = "oauth2_client_registration_info";
362 public static final String OAUTH2_CLIENT_REGISTRATION_COLUMN_FAMILY_NAME = "oauth2_client_registration"; 362 public static final String OAUTH2_CLIENT_REGISTRATION_COLUMN_FAMILY_NAME = "oauth2_client_registration";
  363 + public static final String OAUTH2_CLIENT_REGISTRATION_TO_DOMAIN_COLUMN_FAMILY_NAME = "oauth2_client_registration_to_domain";
363 public static final String OAUTH2_CLIENT_REGISTRATION_TEMPLATE_COLUMN_FAMILY_NAME = "oauth2_client_registration_template"; 364 public static final String OAUTH2_CLIENT_REGISTRATION_TEMPLATE_COLUMN_FAMILY_NAME = "oauth2_client_registration_template";
  365 + public static final String OAUTH2_ENABLED_PROPERTY = "enabled";
364 public static final String OAUTH2_TEMPLATE_PROVIDER_ID_PROPERTY = "provider_id"; 366 public static final String OAUTH2_TEMPLATE_PROVIDER_ID_PROPERTY = "provider_id";
  367 + public static final String OAUTH2_CLIENT_REGISTRATION_INFO_ID_PROPERTY = "client_registration_info_id";
365 public static final String OAUTH2_DOMAIN_NAME_PROPERTY = "domain_name"; 368 public static final String OAUTH2_DOMAIN_NAME_PROPERTY = "domain_name";
  369 + public static final String OAUTH2_DOMAIN_SCHEME_PROPERTY = "domain_scheme";
366 public static final String OAUTH2_CLIENT_ID_PROPERTY = "client_id"; 370 public static final String OAUTH2_CLIENT_ID_PROPERTY = "client_id";
367 public static final String OAUTH2_CLIENT_SECRET_PROPERTY = "client_secret"; 371 public static final String OAUTH2_CLIENT_SECRET_PROPERTY = "client_secret";
368 public static final String OAUTH2_AUTHORIZATION_URI_PROPERTY = "authorization_uri"; 372 public static final String OAUTH2_AUTHORIZATION_URI_PROPERTY = "authorization_uri";
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.model.sql;
  17 +
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import lombok.Data;
  20 +import lombok.EqualsAndHashCode;
  21 +import org.hibernate.annotations.Type;
  22 +import org.hibernate.annotations.TypeDef;
  23 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
  24 +import org.thingsboard.server.common.data.oauth2.*;
  25 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  26 +import org.thingsboard.server.dao.model.ModelConstants;
  27 +import org.thingsboard.server.dao.util.mapping.JsonStringType;
  28 +
  29 +import javax.persistence.*;
  30 +import java.util.Arrays;
  31 +
  32 +@Data
  33 +@EqualsAndHashCode(callSuper = true)
  34 +@TypeDef(name = "json", typeClass = JsonStringType.class)
  35 +@MappedSuperclass
  36 +public abstract class AbstractOAuth2ClientRegistrationInfoEntity<T extends OAuth2ClientRegistrationInfo> extends BaseSqlEntity<T> {
  37 +
  38 + @Column(name = ModelConstants.OAUTH2_ENABLED_PROPERTY)
  39 + private Boolean enabled;
  40 + @Column(name = ModelConstants.OAUTH2_CLIENT_ID_PROPERTY)
  41 + private String clientId;
  42 + @Column(name = ModelConstants.OAUTH2_CLIENT_SECRET_PROPERTY)
  43 + private String clientSecret;
  44 + @Column(name = ModelConstants.OAUTH2_AUTHORIZATION_URI_PROPERTY)
  45 + private String authorizationUri;
  46 + @Column(name = ModelConstants.OAUTH2_TOKEN_URI_PROPERTY)
  47 + private String tokenUri;
  48 + @Column(name = ModelConstants.OAUTH2_SCOPE_PROPERTY)
  49 + private String scope;
  50 + @Column(name = ModelConstants.OAUTH2_USER_INFO_URI_PROPERTY)
  51 + private String userInfoUri;
  52 + @Column(name = ModelConstants.OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY)
  53 + private String userNameAttributeName;
  54 + @Column(name = ModelConstants.OAUTH2_JWK_SET_URI_PROPERTY)
  55 + private String jwkSetUri;
  56 + @Column(name = ModelConstants.OAUTH2_CLIENT_AUTHENTICATION_METHOD_PROPERTY)
  57 + private String clientAuthenticationMethod;
  58 + @Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_LABEL_PROPERTY)
  59 + private String loginButtonLabel;
  60 + @Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_ICON_PROPERTY)
  61 + private String loginButtonIcon;
  62 + @Column(name = ModelConstants.OAUTH2_ALLOW_USER_CREATION_PROPERTY)
  63 + private Boolean allowUserCreation;
  64 + @Column(name = ModelConstants.OAUTH2_ACTIVATE_USER_PROPERTY)
  65 + private Boolean activateUser;
  66 + @Enumerated(EnumType.STRING)
  67 + @Column(name = ModelConstants.OAUTH2_MAPPER_TYPE_PROPERTY)
  68 + private MapperType type;
  69 + @Column(name = ModelConstants.OAUTH2_EMAIL_ATTRIBUTE_KEY_PROPERTY)
  70 + private String emailAttributeKey;
  71 + @Column(name = ModelConstants.OAUTH2_FIRST_NAME_ATTRIBUTE_KEY_PROPERTY)
  72 + private String firstNameAttributeKey;
  73 + @Column(name = ModelConstants.OAUTH2_LAST_NAME_ATTRIBUTE_KEY_PROPERTY)
  74 + private String lastNameAttributeKey;
  75 + @Enumerated(EnumType.STRING)
  76 + @Column(name = ModelConstants.OAUTH2_TENANT_NAME_STRATEGY_PROPERTY)
  77 + private TenantNameStrategyType tenantNameStrategy;
  78 + @Column(name = ModelConstants.OAUTH2_TENANT_NAME_PATTERN_PROPERTY)
  79 + private String tenantNamePattern;
  80 + @Column(name = ModelConstants.OAUTH2_CUSTOMER_NAME_PATTERN_PROPERTY)
  81 + private String customerNamePattern;
  82 + @Column(name = ModelConstants.OAUTH2_DEFAULT_DASHBOARD_NAME_PROPERTY)
  83 + private String defaultDashboardName;
  84 + @Column(name = ModelConstants.OAUTH2_ALWAYS_FULL_SCREEN_PROPERTY)
  85 + private Boolean alwaysFullScreen;
  86 + @Column(name = ModelConstants.OAUTH2_MAPPER_URL_PROPERTY)
  87 + private String url;
  88 + @Column(name = ModelConstants.OAUTH2_MAPPER_USERNAME_PROPERTY)
  89 + private String username;
  90 + @Column(name = ModelConstants.OAUTH2_MAPPER_PASSWORD_PROPERTY)
  91 + private String password;
  92 + @Column(name = ModelConstants.OAUTH2_MAPPER_SEND_TOKEN_PROPERTY)
  93 + private Boolean sendToken;
  94 +
  95 + @Type(type = "json")
  96 + @Column(name = ModelConstants.OAUTH2_ADDITIONAL_INFO_PROPERTY)
  97 + private JsonNode additionalInfo;
  98 +
  99 + public AbstractOAuth2ClientRegistrationInfoEntity() {
  100 + super();
  101 + }
  102 +
  103 + public AbstractOAuth2ClientRegistrationInfoEntity(OAuth2ClientRegistrationInfo clientRegistrationInfo) {
  104 + if (clientRegistrationInfo.getId() != null) {
  105 + this.setUuid(clientRegistrationInfo.getId().getId());
  106 + }
  107 + this.createdTime = clientRegistrationInfo.getCreatedTime();
  108 + this.enabled = clientRegistrationInfo.isEnabled();
  109 + this.clientId = clientRegistrationInfo.getClientId();
  110 + this.clientSecret = clientRegistrationInfo.getClientSecret();
  111 + this.authorizationUri = clientRegistrationInfo.getAuthorizationUri();
  112 + this.tokenUri = clientRegistrationInfo.getAccessTokenUri();
  113 + this.scope = clientRegistrationInfo.getScope().stream().reduce((result, element) -> result + "," + element).orElse("");
  114 + this.userInfoUri = clientRegistrationInfo.getUserInfoUri();
  115 + this.userNameAttributeName = clientRegistrationInfo.getUserNameAttributeName();
  116 + this.jwkSetUri = clientRegistrationInfo.getJwkSetUri();
  117 + this.clientAuthenticationMethod = clientRegistrationInfo.getClientAuthenticationMethod();
  118 + this.loginButtonLabel = clientRegistrationInfo.getLoginButtonLabel();
  119 + this.loginButtonIcon = clientRegistrationInfo.getLoginButtonIcon();
  120 + this.additionalInfo = clientRegistrationInfo.getAdditionalInfo();
  121 + OAuth2MapperConfig mapperConfig = clientRegistrationInfo.getMapperConfig();
  122 + if (mapperConfig != null) {
  123 + this.allowUserCreation = mapperConfig.isAllowUserCreation();
  124 + this.activateUser = mapperConfig.isActivateUser();
  125 + this.type = mapperConfig.getType();
  126 + OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic();
  127 + if (basicConfig != null) {
  128 + this.emailAttributeKey = basicConfig.getEmailAttributeKey();
  129 + this.firstNameAttributeKey = basicConfig.getFirstNameAttributeKey();
  130 + this.lastNameAttributeKey = basicConfig.getLastNameAttributeKey();
  131 + this.tenantNameStrategy = basicConfig.getTenantNameStrategy();
  132 + this.tenantNamePattern = basicConfig.getTenantNamePattern();
  133 + this.customerNamePattern = basicConfig.getCustomerNamePattern();
  134 + this.defaultDashboardName = basicConfig.getDefaultDashboardName();
  135 + this.alwaysFullScreen = basicConfig.isAlwaysFullScreen();
  136 + }
  137 + OAuth2CustomMapperConfig customConfig = mapperConfig.getCustom();
  138 + if (customConfig != null) {
  139 + this.url = customConfig.getUrl();
  140 + this.username = customConfig.getUsername();
  141 + this.password = customConfig.getPassword();
  142 + this.sendToken = customConfig.isSendToken();
  143 + }
  144 + }
  145 + }
  146 +
  147 + public AbstractOAuth2ClientRegistrationInfoEntity(OAuth2ClientRegistrationInfoEntity oAuth2ClientRegistrationInfoEntity) {
  148 + this.setId(oAuth2ClientRegistrationInfoEntity.getId());
  149 + this.setCreatedTime(oAuth2ClientRegistrationInfoEntity.getCreatedTime());
  150 + this.enabled = oAuth2ClientRegistrationInfoEntity.getEnabled();
  151 + this.clientId = oAuth2ClientRegistrationInfoEntity.getClientId();
  152 + this.clientSecret = oAuth2ClientRegistrationInfoEntity.getClientSecret();
  153 + this.authorizationUri = oAuth2ClientRegistrationInfoEntity.getAuthorizationUri();
  154 + this.tokenUri = oAuth2ClientRegistrationInfoEntity.getTokenUri();
  155 + this.scope = oAuth2ClientRegistrationInfoEntity.getScope();
  156 + this.userInfoUri = oAuth2ClientRegistrationInfoEntity.getUserInfoUri();
  157 + this.userNameAttributeName = oAuth2ClientRegistrationInfoEntity.getUserNameAttributeName();
  158 + this.jwkSetUri = oAuth2ClientRegistrationInfoEntity.getJwkSetUri();
  159 + this.clientAuthenticationMethod = oAuth2ClientRegistrationInfoEntity.getClientAuthenticationMethod();
  160 + this.loginButtonLabel = oAuth2ClientRegistrationInfoEntity.getLoginButtonLabel();
  161 + this.loginButtonIcon = oAuth2ClientRegistrationInfoEntity.getLoginButtonIcon();
  162 + this.additionalInfo = oAuth2ClientRegistrationInfoEntity.getAdditionalInfo();
  163 + this.allowUserCreation = oAuth2ClientRegistrationInfoEntity.getAllowUserCreation();
  164 + this.activateUser = oAuth2ClientRegistrationInfoEntity.getActivateUser();
  165 + this.type = oAuth2ClientRegistrationInfoEntity.getType();
  166 + this.emailAttributeKey = oAuth2ClientRegistrationInfoEntity.getEmailAttributeKey();
  167 + this.firstNameAttributeKey = oAuth2ClientRegistrationInfoEntity.getFirstNameAttributeKey();
  168 + this.lastNameAttributeKey = oAuth2ClientRegistrationInfoEntity.getLastNameAttributeKey();
  169 + this.tenantNameStrategy = oAuth2ClientRegistrationInfoEntity.getTenantNameStrategy();
  170 + this.tenantNamePattern = oAuth2ClientRegistrationInfoEntity.getTenantNamePattern();
  171 + this.customerNamePattern = oAuth2ClientRegistrationInfoEntity.getCustomerNamePattern();
  172 + this.defaultDashboardName = oAuth2ClientRegistrationInfoEntity.getDefaultDashboardName();
  173 + this.alwaysFullScreen = oAuth2ClientRegistrationInfoEntity.getAlwaysFullScreen();
  174 + this.url = oAuth2ClientRegistrationInfoEntity.getUrl();
  175 + this.username = oAuth2ClientRegistrationInfoEntity.getUsername();
  176 + this.password = oAuth2ClientRegistrationInfoEntity.getPassword();
  177 + this.sendToken = oAuth2ClientRegistrationInfoEntity.getSendToken();
  178 + }
  179 +
  180 +
  181 + protected OAuth2ClientRegistrationInfo toOAuth2ClientRegistrationInfo() {
  182 + OAuth2ClientRegistrationInfo clientRegistrationInfo = new OAuth2ClientRegistrationInfo();
  183 + clientRegistrationInfo.setId(new OAuth2ClientRegistrationInfoId(id));
  184 + clientRegistrationInfo.setEnabled(enabled);
  185 + clientRegistrationInfo.setCreatedTime(createdTime);
  186 + clientRegistrationInfo.setAdditionalInfo(additionalInfo);
  187 + clientRegistrationInfo.setMapperConfig(
  188 + OAuth2MapperConfig.builder()
  189 + .allowUserCreation(allowUserCreation)
  190 + .activateUser(activateUser)
  191 + .type(type)
  192 + .basic(
  193 + type == MapperType.BASIC ?
  194 + OAuth2BasicMapperConfig.builder()
  195 + .emailAttributeKey(emailAttributeKey)
  196 + .firstNameAttributeKey(firstNameAttributeKey)
  197 + .lastNameAttributeKey(lastNameAttributeKey)
  198 + .tenantNameStrategy(tenantNameStrategy)
  199 + .tenantNamePattern(tenantNamePattern)
  200 + .customerNamePattern(customerNamePattern)
  201 + .defaultDashboardName(defaultDashboardName)
  202 + .alwaysFullScreen(alwaysFullScreen)
  203 + .build()
  204 + : null
  205 + )
  206 + .custom(
  207 + type == MapperType.CUSTOM ?
  208 + OAuth2CustomMapperConfig.builder()
  209 + .url(url)
  210 + .username(username)
  211 + .password(password)
  212 + .sendToken(sendToken)
  213 + .build()
  214 + : null
  215 + )
  216 + .build()
  217 + );
  218 + clientRegistrationInfo.setClientId(clientId);
  219 + clientRegistrationInfo.setClientSecret(clientSecret);
  220 + clientRegistrationInfo.setAuthorizationUri(authorizationUri);
  221 + clientRegistrationInfo.setAccessTokenUri(tokenUri);
  222 + clientRegistrationInfo.setScope(Arrays.asList(scope.split(",")));
  223 + clientRegistrationInfo.setUserInfoUri(userInfoUri);
  224 + clientRegistrationInfo.setUserNameAttributeName(userNameAttributeName);
  225 + clientRegistrationInfo.setJwkSetUri(jwkSetUri);
  226 + clientRegistrationInfo.setClientAuthenticationMethod(clientAuthenticationMethod);
  227 + clientRegistrationInfo.setLoginButtonLabel(loginButtonLabel);
  228 + clientRegistrationInfo.setLoginButtonIcon(loginButtonIcon);
  229 + return clientRegistrationInfo;
  230 + }
  231 +}
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.oauth2.ExtendedOAuth2ClientRegistrationInfo;
  21 +import org.thingsboard.server.common.data.oauth2.SchemeType;
  22 +
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +public class ExtendedOAuth2ClientRegistrationInfoEntity extends AbstractOAuth2ClientRegistrationInfoEntity<ExtendedOAuth2ClientRegistrationInfo> {
  26 +
  27 + private String domainName;
  28 + private SchemeType domainScheme;
  29 +
  30 + public ExtendedOAuth2ClientRegistrationInfoEntity() {
  31 + super();
  32 + }
  33 +
  34 + public ExtendedOAuth2ClientRegistrationInfoEntity(OAuth2ClientRegistrationInfoEntity oAuth2ClientRegistrationInfoEntity,
  35 + String domainName,
  36 + SchemeType domainScheme) {
  37 + super(oAuth2ClientRegistrationInfoEntity);
  38 + this.domainName = domainName;
  39 + this.domainScheme = domainScheme;
  40 + }
  41 +
  42 + @Override
  43 + public ExtendedOAuth2ClientRegistrationInfo toData() {
  44 + return new ExtendedOAuth2ClientRegistrationInfo(super.toOAuth2ClientRegistrationInfo(),
  45 + domainScheme,
  46 + domainName);
  47 + }
  48 +}
@@ -15,13 +15,11 @@ @@ -15,13 +15,11 @@
15 */ 15 */
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;  
19 import lombok.Data; 18 import lombok.Data;
20 import lombok.EqualsAndHashCode; 19 import lombok.EqualsAndHashCode;
21 -import org.hibernate.annotations.Type;  
22 import org.hibernate.annotations.TypeDef; 20 import org.hibernate.annotations.TypeDef;
23 import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId; 21 import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;
24 -import org.thingsboard.server.common.data.id.TenantId; 22 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
25 import org.thingsboard.server.common.data.oauth2.*; 23 import org.thingsboard.server.common.data.oauth2.*;
26 import org.thingsboard.server.dao.model.BaseSqlEntity; 24 import org.thingsboard.server.dao.model.BaseSqlEntity;
27 import org.thingsboard.server.dao.model.ModelConstants; 25 import org.thingsboard.server.dao.model.ModelConstants;
@@ -38,70 +36,15 @@ import java.util.UUID; @@ -38,70 +36,15 @@ import java.util.UUID;
38 @Table(name = ModelConstants.OAUTH2_CLIENT_REGISTRATION_COLUMN_FAMILY_NAME) 36 @Table(name = ModelConstants.OAUTH2_CLIENT_REGISTRATION_COLUMN_FAMILY_NAME)
39 public class OAuth2ClientRegistrationEntity extends BaseSqlEntity<OAuth2ClientRegistration> { 37 public class OAuth2ClientRegistrationEntity extends BaseSqlEntity<OAuth2ClientRegistration> {
40 38
41 - @Column(name = ModelConstants.OAUTH2_ENABLED_PROPERTY)  
42 - private Boolean enabled; 39 + @Column(name = ModelConstants.OAUTH2_CLIENT_REGISTRATION_INFO_ID_PROPERTY, columnDefinition = "uuid")
  40 + private UUID clientRegistrationInfoId;
  41 +
43 @Column(name = ModelConstants.OAUTH2_DOMAIN_NAME_PROPERTY) 42 @Column(name = ModelConstants.OAUTH2_DOMAIN_NAME_PROPERTY)
44 private String domainName; 43 private String domainName;
45 - @Column(name = ModelConstants.OAUTH2_CLIENT_ID_PROPERTY)  
46 - private String clientId;  
47 - @Column(name = ModelConstants.OAUTH2_CLIENT_SECRET_PROPERTY)  
48 - private String clientSecret;  
49 - @Column(name = ModelConstants.OAUTH2_AUTHORIZATION_URI_PROPERTY)  
50 - private String authorizationUri;  
51 - @Column(name = ModelConstants.OAUTH2_TOKEN_URI_PROPERTY)  
52 - private String tokenUri;  
53 - @Column(name = ModelConstants.OAUTH2_REDIRECT_URI_TEMPLATE_PROPERTY)  
54 - private String redirectUriTemplate;  
55 - @Column(name = ModelConstants.OAUTH2_SCOPE_PROPERTY)  
56 - private String scope;  
57 - @Column(name = ModelConstants.OAUTH2_USER_INFO_URI_PROPERTY)  
58 - private String userInfoUri;  
59 - @Column(name = ModelConstants.OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY)  
60 - private String userNameAttributeName;  
61 - @Column(name = ModelConstants.OAUTH2_JWK_SET_URI_PROPERTY)  
62 - private String jwkSetUri;  
63 - @Column(name = ModelConstants.OAUTH2_CLIENT_AUTHENTICATION_METHOD_PROPERTY)  
64 - private String clientAuthenticationMethod;  
65 - @Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_LABEL_PROPERTY)  
66 - private String loginButtonLabel;  
67 - @Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_ICON_PROPERTY)  
68 - private String loginButtonIcon;  
69 - @Column(name = ModelConstants.OAUTH2_ALLOW_USER_CREATION_PROPERTY)  
70 - private Boolean allowUserCreation;  
71 - @Column(name = ModelConstants.OAUTH2_ACTIVATE_USER_PROPERTY)  
72 - private Boolean activateUser;  
73 - @Enumerated(EnumType.STRING)  
74 - @Column(name = ModelConstants.OAUTH2_MAPPER_TYPE_PROPERTY)  
75 - private MapperType type;  
76 - @Column(name = ModelConstants.OAUTH2_EMAIL_ATTRIBUTE_KEY_PROPERTY)  
77 - private String emailAttributeKey;  
78 - @Column(name = ModelConstants.OAUTH2_FIRST_NAME_ATTRIBUTE_KEY_PROPERTY)  
79 - private String firstNameAttributeKey;  
80 - @Column(name = ModelConstants.OAUTH2_LAST_NAME_ATTRIBUTE_KEY_PROPERTY)  
81 - private String lastNameAttributeKey;  
82 - @Enumerated(EnumType.STRING)  
83 - @Column(name = ModelConstants.OAUTH2_TENANT_NAME_STRATEGY_PROPERTY)  
84 - private TenantNameStrategyType tenantNameStrategy;  
85 - @Column(name = ModelConstants.OAUTH2_TENANT_NAME_PATTERN_PROPERTY)  
86 - private String tenantNamePattern;  
87 - @Column(name = ModelConstants.OAUTH2_CUSTOMER_NAME_PATTERN_PROPERTY)  
88 - private String customerNamePattern;  
89 - @Column(name = ModelConstants.OAUTH2_DEFAULT_DASHBOARD_NAME_PROPERTY)  
90 - private String defaultDashboardName;  
91 - @Column(name = ModelConstants.OAUTH2_ALWAYS_FULL_SCREEN_PROPERTY)  
92 - private Boolean alwaysFullScreen;  
93 - @Column(name = ModelConstants.OAUTH2_MAPPER_URL_PROPERTY)  
94 - private String url;  
95 - @Column(name = ModelConstants.OAUTH2_MAPPER_USERNAME_PROPERTY)  
96 - private String username;  
97 - @Column(name = ModelConstants.OAUTH2_MAPPER_PASSWORD_PROPERTY)  
98 - private String password;  
99 - @Column(name = ModelConstants.OAUTH2_MAPPER_SEND_TOKEN_PROPERTY)  
100 - private Boolean sendToken;  
101 44
102 - @Type(type = "json")  
103 - @Column(name = ModelConstants.OAUTH2_ADDITIONAL_INFO_PROPERTY)  
104 - private JsonNode additionalInfo; 45 + @Enumerated(EnumType.STRING)
  46 + @Column(name = ModelConstants.OAUTH2_DOMAIN_SCHEME_PROPERTY)
  47 + private SchemeType domainScheme;
105 48
106 public OAuth2ClientRegistrationEntity() { 49 public OAuth2ClientRegistrationEntity() {
107 super(); 50 super();
@@ -111,99 +54,22 @@ public class OAuth2ClientRegistrationEntity extends BaseSqlEntity<OAuth2ClientRe @@ -111,99 +54,22 @@ public class OAuth2ClientRegistrationEntity extends BaseSqlEntity<OAuth2ClientRe
111 if (clientRegistration.getId() != null) { 54 if (clientRegistration.getId() != null) {
112 this.setUuid(clientRegistration.getId().getId()); 55 this.setUuid(clientRegistration.getId().getId());
113 } 56 }
114 - this.enabled = clientRegistration.isEnabled();  
115 - this.domainName = clientRegistration.getDomainName();  
116 - this.createdTime = clientRegistration.getCreatedTime();  
117 - this.clientId = clientRegistration.getClientId();  
118 - this.clientSecret = clientRegistration.getClientSecret();  
119 - this.authorizationUri = clientRegistration.getAuthorizationUri();  
120 - this.tokenUri = clientRegistration.getAccessTokenUri();  
121 - this.redirectUriTemplate = clientRegistration.getRedirectUriTemplate();  
122 - this.scope = clientRegistration.getScope().stream().reduce((result, element) -> result + "," + element).orElse("");  
123 - this.userInfoUri = clientRegistration.getUserInfoUri();  
124 - this.userNameAttributeName = clientRegistration.getUserNameAttributeName();  
125 - this.jwkSetUri = clientRegistration.getJwkSetUri();  
126 - this.clientAuthenticationMethod = clientRegistration.getClientAuthenticationMethod();  
127 - this.loginButtonLabel = clientRegistration.getLoginButtonLabel();  
128 - this.loginButtonIcon = clientRegistration.getLoginButtonIcon();  
129 - this.additionalInfo = clientRegistration.getAdditionalInfo();  
130 - OAuth2MapperConfig mapperConfig = clientRegistration.getMapperConfig();  
131 - if (mapperConfig != null) {  
132 - this.allowUserCreation = mapperConfig.isAllowUserCreation();  
133 - this.activateUser = mapperConfig.isActivateUser();  
134 - this.type = mapperConfig.getType();  
135 - OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic();  
136 - if (basicConfig != null) {  
137 - this.emailAttributeKey = basicConfig.getEmailAttributeKey();  
138 - this.firstNameAttributeKey = basicConfig.getFirstNameAttributeKey();  
139 - this.lastNameAttributeKey = basicConfig.getLastNameAttributeKey();  
140 - this.tenantNameStrategy = basicConfig.getTenantNameStrategy();  
141 - this.tenantNamePattern = basicConfig.getTenantNamePattern();  
142 - this.customerNamePattern = basicConfig.getCustomerNamePattern();  
143 - this.defaultDashboardName = basicConfig.getDefaultDashboardName();  
144 - this.alwaysFullScreen = basicConfig.isAlwaysFullScreen();  
145 - }  
146 - OAuth2CustomMapperConfig customConfig = mapperConfig.getCustom();  
147 - if (customConfig != null) {  
148 - this.url = customConfig.getUrl();  
149 - this.username = customConfig.getUsername();  
150 - this.password = customConfig.getPassword();  
151 - this.sendToken = customConfig.isSendToken();  
152 - } 57 + if (clientRegistration.getClientRegistrationId() != null){
  58 + this.clientRegistrationInfoId = clientRegistration.getClientRegistrationId().getId();
153 } 59 }
  60 + this.createdTime = clientRegistration.getCreatedTime();
  61 + this.domainName = clientRegistration.getDomainName();
  62 + this.domainScheme = clientRegistration.getDomainScheme();
154 } 63 }
155 64
156 @Override 65 @Override
157 public OAuth2ClientRegistration toData() { 66 public OAuth2ClientRegistration toData() {
158 OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration(); 67 OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration();
159 clientRegistration.setId(new OAuth2ClientRegistrationId(id)); 68 clientRegistration.setId(new OAuth2ClientRegistrationId(id));
160 - clientRegistration.setEnabled(enabled); 69 + clientRegistration.setClientRegistrationId(new OAuth2ClientRegistrationInfoId(clientRegistrationInfoId));
161 clientRegistration.setCreatedTime(createdTime); 70 clientRegistration.setCreatedTime(createdTime);
162 clientRegistration.setDomainName(domainName); 71 clientRegistration.setDomainName(domainName);
163 - clientRegistration.setAdditionalInfo(additionalInfo);  
164 - clientRegistration.setMapperConfig(  
165 - OAuth2MapperConfig.builder()  
166 - .allowUserCreation(allowUserCreation)  
167 - .activateUser(activateUser)  
168 - .type(type)  
169 - .basic(  
170 - type == MapperType.BASIC ?  
171 - OAuth2BasicMapperConfig.builder()  
172 - .emailAttributeKey(emailAttributeKey)  
173 - .firstNameAttributeKey(firstNameAttributeKey)  
174 - .lastNameAttributeKey(lastNameAttributeKey)  
175 - .tenantNameStrategy(tenantNameStrategy)  
176 - .tenantNamePattern(tenantNamePattern)  
177 - .customerNamePattern(customerNamePattern)  
178 - .defaultDashboardName(defaultDashboardName)  
179 - .alwaysFullScreen(alwaysFullScreen)  
180 - .build()  
181 - : null  
182 - )  
183 - .custom(  
184 - type == MapperType.CUSTOM ?  
185 - OAuth2CustomMapperConfig.builder()  
186 - .url(url)  
187 - .username(username)  
188 - .password(password)  
189 - .sendToken(sendToken)  
190 - .build()  
191 - : null  
192 - )  
193 - .build()  
194 - );  
195 - clientRegistration.setClientId(clientId);  
196 - clientRegistration.setClientSecret(clientSecret);  
197 - clientRegistration.setAuthorizationUri(authorizationUri);  
198 - clientRegistration.setAccessTokenUri(tokenUri);  
199 - clientRegistration.setRedirectUriTemplate(redirectUriTemplate);  
200 - clientRegistration.setScope(Arrays.asList(scope.split(",")));  
201 - clientRegistration.setUserInfoUri(userInfoUri);  
202 - clientRegistration.setUserNameAttributeName(userNameAttributeName);  
203 - clientRegistration.setJwkSetUri(jwkSetUri);  
204 - clientRegistration.setClientAuthenticationMethod(clientAuthenticationMethod);  
205 - clientRegistration.setLoginButtonLabel(loginButtonLabel);  
206 - clientRegistration.setLoginButtonIcon(loginButtonIcon); 72 + clientRegistration.setDomainScheme(domainScheme);
207 return clientRegistration; 73 return clientRegistration;
208 } 74 }
209 } 75 }
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.hibernate.annotations.TypeDef;
  21 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
  22 +import org.thingsboard.server.dao.model.ModelConstants;
  23 +import org.thingsboard.server.dao.util.mapping.JsonStringType;
  24 +
  25 +import javax.persistence.Entity;
  26 +import javax.persistence.Table;
  27 +
  28 +@Data
  29 +@EqualsAndHashCode(callSuper = true)
  30 +@Entity
  31 +@TypeDef(name = "json", typeClass = JsonStringType.class)
  32 +@Table(name = ModelConstants.OAUTH2_CLIENT_REGISTRATION_INFO_COLUMN_FAMILY_NAME)
  33 +public class OAuth2ClientRegistrationInfoEntity extends AbstractOAuth2ClientRegistrationInfoEntity<OAuth2ClientRegistrationInfo> {
  34 +
  35 + public OAuth2ClientRegistrationInfoEntity() {
  36 + super();
  37 + }
  38 +
  39 + public OAuth2ClientRegistrationInfoEntity(OAuth2ClientRegistrationInfo clientRegistration) {
  40 + super(clientRegistration);
  41 + }
  42 +
  43 + public OAuth2ClientRegistrationInfoEntity(OAuth2ClientRegistrationInfoEntity oAuth2ClientRegistrationInfoEntity) {
  44 + super(oAuth2ClientRegistrationInfoEntity);
  45 + }
  46 +
  47 + @Override
  48 + public OAuth2ClientRegistrationInfo toData() {
  49 + return super.toOAuth2ClientRegistrationInfo();
  50 + }
  51 +}
@@ -21,8 +21,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio @@ -21,8 +21,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
21 import org.springframework.security.oauth2.core.AuthorizationGrantType; 21 import org.springframework.security.oauth2.core.AuthorizationGrantType;
22 import org.springframework.security.oauth2.core.ClientAuthenticationMethod; 22 import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
23 import org.springframework.stereotype.Component; 23 import org.springframework.stereotype.Component;
24 -import org.thingsboard.server.common.data.oauth2.ExtendedOAuth2ClientRegistration;  
25 -import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; 24 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
26 25
27 import java.util.UUID; 26 import java.util.UUID;
28 27
@@ -34,12 +33,12 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep @@ -34,12 +33,12 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep
34 33
35 @Override 34 @Override
36 public ClientRegistration findByRegistrationId(String registrationId) { 35 public ClientRegistration findByRegistrationId(String registrationId) {
37 - OAuth2ClientRegistration oAuth2ClientRegistration = oAuth2Service.findClientRegistration(UUID.fromString(registrationId));  
38 - return oAuth2ClientRegistration == null ?  
39 - null : toSpringClientRegistration(oAuth2ClientRegistration); 36 + OAuth2ClientRegistrationInfo oAuth2ClientRegistrationInfo = oAuth2Service.findClientRegistrationInfo(UUID.fromString(registrationId));
  37 + return oAuth2ClientRegistrationInfo == null ?
  38 + null : toSpringClientRegistration(oAuth2ClientRegistrationInfo);
40 } 39 }
41 40
42 - private ClientRegistration toSpringClientRegistration(OAuth2ClientRegistration localClientRegistration){ 41 + private ClientRegistration toSpringClientRegistration(OAuth2ClientRegistrationInfo localClientRegistration){
43 String registrationId = localClientRegistration.getUuidId().toString(); 42 String registrationId = localClientRegistration.getUuidId().toString();
44 return ClientRegistration.withRegistrationId(registrationId) 43 return ClientRegistration.withRegistrationId(registrationId)
45 .clientName(localClientRegistration.getName()) 44 .clientName(localClientRegistration.getName())
@@ -47,7 +46,6 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep @@ -47,7 +46,6 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep
47 .authorizationUri(localClientRegistration.getAuthorizationUri()) 46 .authorizationUri(localClientRegistration.getAuthorizationUri())
48 .clientSecret(localClientRegistration.getClientSecret()) 47 .clientSecret(localClientRegistration.getClientSecret())
49 .tokenUri(localClientRegistration.getAccessTokenUri()) 48 .tokenUri(localClientRegistration.getAccessTokenUri())
50 - .redirectUriTemplate(localClientRegistration.getRedirectUriTemplate())  
51 .scope(localClientRegistration.getScope()) 49 .scope(localClientRegistration.getScope())
52 .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) 50 .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
53 .userInfoUri(localClientRegistration.getUserInfoUri()) 51 .userInfoUri(localClientRegistration.getUserInfoUri())
@@ -18,13 +18,6 @@ package org.thingsboard.server.dao.oauth2; @@ -18,13 +18,6 @@ package org.thingsboard.server.dao.oauth2;
18 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; 18 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration;
19 import org.thingsboard.server.dao.Dao; 19 import org.thingsboard.server.dao.Dao;
20 20
21 -import java.util.List;  
22 -import java.util.UUID;  
23 -  
24 public interface OAuth2ClientRegistrationDao extends Dao<OAuth2ClientRegistration> { 21 public interface OAuth2ClientRegistrationDao extends Dao<OAuth2ClientRegistration> {
25 - List<OAuth2ClientRegistration> findAll();  
26 -  
27 - List<OAuth2ClientRegistration> findByDomainName(String domainName);  
28 -  
29 - int removeByDomainName(String domainName); 22 + void deleteAll();
30 } 23 }
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.oauth2;
  17 +
  18 +import org.thingsboard.server.common.data.oauth2.ExtendedOAuth2ClientRegistrationInfo;
  19 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
  20 +import org.thingsboard.server.common.data.oauth2.SchemeType;
  21 +import org.thingsboard.server.dao.Dao;
  22 +
  23 +import java.util.List;
  24 +import java.util.Set;
  25 +
  26 +public interface OAuth2ClientRegistrationInfoDao extends Dao<OAuth2ClientRegistrationInfo> {
  27 + List<OAuth2ClientRegistrationInfo> findAll();
  28 +
  29 + List<ExtendedOAuth2ClientRegistrationInfo> findAllExtended();
  30 +
  31 + List<OAuth2ClientRegistrationInfo> findByDomainSchemesAndDomainName(List<SchemeType> domainSchemes, String domainName);
  32 +
  33 + void deleteAll();
  34 +}
@@ -19,11 +19,11 @@ import lombok.extern.slf4j.Slf4j; @@ -19,11 +19,11 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
21 import org.springframework.util.StringUtils; 21 import org.springframework.util.StringUtils;
22 -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId;  
23 import org.thingsboard.server.common.data.id.TenantId; 22 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.oauth2.*; 23 import org.thingsboard.server.common.data.oauth2.*;
25 import org.thingsboard.server.dao.entity.AbstractEntityService; 24 import org.thingsboard.server.dao.entity.AbstractEntityService;
26 import org.thingsboard.server.dao.exception.DataValidationException; 25 import org.thingsboard.server.dao.exception.DataValidationException;
  26 +import org.thingsboard.server.dao.exception.IncorrectParameterException;
27 27
28 import javax.transaction.Transactional; 28 import javax.transaction.Transactional;
29 import java.util.*; 29 import java.util.*;
@@ -39,78 +39,89 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se @@ -39,78 +39,89 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se
39 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; 39 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
40 public static final String INCORRECT_CLIENT_REGISTRATION_ID = "Incorrect clientRegistrationId "; 40 public static final String INCORRECT_CLIENT_REGISTRATION_ID = "Incorrect clientRegistrationId ";
41 public static final String INCORRECT_DOMAIN_NAME = "Incorrect domainName "; 41 public static final String INCORRECT_DOMAIN_NAME = "Incorrect domainName ";
  42 + public static final String INCORRECT_DOMAIN_SCHEME = "Incorrect domainScheme ";
42 43
43 @Autowired 44 @Autowired
  45 + private OAuth2ClientRegistrationInfoDao clientRegistrationInfoDao;
  46 + @Autowired
44 private OAuth2ClientRegistrationDao clientRegistrationDao; 47 private OAuth2ClientRegistrationDao clientRegistrationDao;
45 48
46 @Override 49 @Override
47 - public List<OAuth2ClientInfo> getOAuth2Clients(String domainName) {  
48 - log.trace("Executing getOAuth2Clients [{}]", domainName); 50 + public List<OAuth2ClientInfo> getOAuth2Clients(String domainSchemeStr, String domainName) {
  51 + log.trace("Executing getOAuth2Clients [{}://{}]", domainSchemeStr, domainName);
  52 + if (domainSchemeStr == null) {
  53 + throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME);
  54 + }
  55 + SchemeType domainScheme;
  56 + try {
  57 + domainScheme = SchemeType.valueOf(domainSchemeStr.toUpperCase());
  58 + } catch (IllegalArgumentException e){
  59 + throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME);
  60 + }
49 validateString(domainName, INCORRECT_DOMAIN_NAME + domainName); 61 validateString(domainName, INCORRECT_DOMAIN_NAME + domainName);
50 - return clientRegistrationDao.findByDomainName(domainName).stream()  
51 - .filter(OAuth2ClientRegistration::isEnabled) 62 + return clientRegistrationInfoDao.findByDomainSchemesAndDomainName(Arrays.asList(domainScheme, SchemeType.MIXED), domainName).stream()
  63 + .filter(OAuth2ClientRegistrationInfo::isEnabled)
52 .map(OAuth2Utils::toClientInfo) 64 .map(OAuth2Utils::toClientInfo)
53 .collect(Collectors.toList()); 65 .collect(Collectors.toList());
54 } 66 }
55 67
56 @Override 68 @Override
57 @Transactional 69 @Transactional
58 - public OAuth2ClientsParams saveOAuth2Params(OAuth2ClientsParams oauth2Params) { 70 + public void saveOAuth2Params(OAuth2ClientsParams oauth2Params) {
59 log.trace("Executing saveOAuth2Params [{}]", oauth2Params); 71 log.trace("Executing saveOAuth2Params [{}]", oauth2Params);
60 clientParamsValidator.accept(oauth2Params); 72 clientParamsValidator.accept(oauth2Params);
61 - List<OAuth2ClientRegistration> inputClientRegistrations = OAuth2Utils.toClientRegistrations(oauth2Params);  
62 - List<OAuth2ClientRegistration> savedClientRegistrations = inputClientRegistrations.stream()  
63 - .map(clientRegistration -> clientRegistrationDao.save(TenantId.SYS_TENANT_ID, clientRegistration))  
64 - .collect(Collectors.toList());  
65 - return OAuth2Utils.toOAuth2Params(savedClientRegistrations); 73 + clientRegistrationDao.deleteAll();
  74 + clientRegistrationInfoDao.deleteAll();
  75 + oauth2Params.getOAuth2DomainDtos().forEach(domainParams -> {
  76 + domainParams.getClientRegistrations().forEach(clientRegistrationDto -> {
  77 + OAuth2ClientRegistrationInfo oAuth2ClientRegistrationInfo = OAuth2Utils.toClientRegistrationInfo(oauth2Params.isEnabled(), clientRegistrationDto);
  78 + OAuth2ClientRegistrationInfo savedClientRegistrationInfo = clientRegistrationInfoDao.save(TenantId.SYS_TENANT_ID, oAuth2ClientRegistrationInfo);
  79 + domainParams.getDomainInfos().forEach(domainInfo -> {
  80 + OAuth2ClientRegistration oAuth2ClientRegistration = OAuth2Utils.toClientRegistration(savedClientRegistrationInfo.getId(),
  81 + domainInfo.getScheme(), domainInfo.getName());
  82 + clientRegistrationDao.save(TenantId.SYS_TENANT_ID, oAuth2ClientRegistration);
  83 + });
  84 + });
  85 + });
66 } 86 }
67 87
68 @Override 88 @Override
69 public OAuth2ClientsParams findOAuth2Params() { 89 public OAuth2ClientsParams findOAuth2Params() {
70 log.trace("Executing findOAuth2Params"); 90 log.trace("Executing findOAuth2Params");
71 - return OAuth2Utils.toOAuth2Params(clientRegistrationDao.findAll());  
72 - }  
73 -  
74 - @Override  
75 - public OAuth2ClientRegistration findClientRegistration(UUID id) {  
76 - log.trace("Executing findClientRegistration [{}]", id);  
77 - validateId(id, INCORRECT_CLIENT_REGISTRATION_ID + id);  
78 - return clientRegistrationDao.findById(null, id);  
79 - }  
80 -  
81 - @Override  
82 - public List<OAuth2ClientRegistration> findAllClientRegistrations() {  
83 - log.trace("Executing findAllClientRegistrations");  
84 - return clientRegistrationDao.findAll(); 91 + List<ExtendedOAuth2ClientRegistrationInfo> extendedInfos = clientRegistrationInfoDao.findAllExtended();
  92 + return OAuth2Utils.toOAuth2Params(extendedInfos);
85 } 93 }
86 94
87 @Override 95 @Override
88 - public void deleteClientRegistrationById(OAuth2ClientRegistrationId id) {  
89 - log.trace("Executing deleteClientRegistrationById [{}]", id); 96 + public OAuth2ClientRegistrationInfo findClientRegistrationInfo(UUID id) {
  97 + log.trace("Executing findClientRegistrationInfo [{}]", id);
90 validateId(id, INCORRECT_CLIENT_REGISTRATION_ID + id); 98 validateId(id, INCORRECT_CLIENT_REGISTRATION_ID + id);
91 - clientRegistrationDao.removeById(TenantId.SYS_TENANT_ID, id.getId()); 99 + return clientRegistrationInfoDao.findById(null, id);
92 } 100 }
93 101
94 @Override 102 @Override
95 - @Transactional  
96 - public void deleteClientRegistrationsByDomain(String domain) {  
97 - log.trace("Executing deleteClientRegistrationsByDomain [{}]", domain);  
98 - validateString(domain, INCORRECT_DOMAIN_NAME + domain);  
99 - clientRegistrationDao.removeByDomainName(domain); 103 + public List<OAuth2ClientRegistrationInfo> findAllClientRegistrationInfos() {
  104 + log.trace("Executing findAllClientRegistrationInfos");
  105 + return clientRegistrationInfoDao.findAll();
100 } 106 }
101 107
102 private final Consumer<OAuth2ClientsParams> clientParamsValidator = oauth2Params -> { 108 private final Consumer<OAuth2ClientsParams> clientParamsValidator = oauth2Params -> {
103 if (oauth2Params == null 109 if (oauth2Params == null
104 - || oauth2Params.getOAuth2DomainDtos() == null  
105 - || oauth2Params.getOAuth2DomainDtos().isEmpty()) { 110 + || oauth2Params.getOAuth2DomainDtos() == null) {
106 throw new DataValidationException("Domain params should be specified!"); 111 throw new DataValidationException("Domain params should be specified!");
107 } 112 }
108 for (OAuth2ClientsDomainParams domainParams : oauth2Params.getOAuth2DomainDtos()) { 113 for (OAuth2ClientsDomainParams domainParams : oauth2Params.getOAuth2DomainDtos()) {
109 - if (StringUtils.isEmpty(domainParams.getDomainName())) {  
110 - throw new DataValidationException("Domain name should be specified!"); 114 + if (domainParams.getDomainInfos() == null
  115 + || domainParams.getDomainInfos().isEmpty()) {
  116 + throw new DataValidationException("List of domain configuration should be specified!");
111 } 117 }
112 - if (StringUtils.isEmpty(domainParams.getRedirectUriTemplate())) {  
113 - throw new DataValidationException("Redirect URI template should be specified!"); 118 + for (DomainInfo domainInfo : domainParams.getDomainInfos()) {
  119 + if (StringUtils.isEmpty(domainInfo.getName())) {
  120 + throw new DataValidationException("Domain name should be specified!");
  121 + }
  122 + if (StringUtils.isEmpty(domainInfo.getScheme())) {
  123 + throw new DataValidationException("Domain scheme should be specified!");
  124 + }
114 } 125 }
115 if (domainParams.getClientRegistrations() == null || domainParams.getClientRegistrations().isEmpty()) { 126 if (domainParams.getClientRegistrations() == null || domainParams.getClientRegistrations().isEmpty()) {
116 throw new DataValidationException("Client registrations should be specified!"); 127 throw new DataValidationException("Client registrations should be specified!");
@@ -15,93 +15,88 @@ @@ -15,93 +15,88 @@
15 */ 15 */
16 package org.thingsboard.server.dao.oauth2; 16 package org.thingsboard.server.dao.oauth2;
17 17
  18 +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId;
18 import org.thingsboard.server.common.data.oauth2.*; 19 import org.thingsboard.server.common.data.oauth2.*;
19 20
20 -import java.util.ArrayList;  
21 -import java.util.HashMap;  
22 -import java.util.List;  
23 -import java.util.Map;  
24 -import java.util.stream.Collectors; 21 +import java.util.*;
25 22
26 public class OAuth2Utils { 23 public class OAuth2Utils {
27 public static final String OAUTH2_AUTHORIZATION_PATH_TEMPLATE = "/oauth2/authorization/%s"; 24 public static final String OAUTH2_AUTHORIZATION_PATH_TEMPLATE = "/oauth2/authorization/%s";
28 25
29 - public static OAuth2ClientInfo toClientInfo(OAuth2ClientRegistration clientRegistration) { 26 + public static OAuth2ClientInfo toClientInfo(OAuth2ClientRegistrationInfo clientRegistrationInfo) {
30 OAuth2ClientInfo client = new OAuth2ClientInfo(); 27 OAuth2ClientInfo client = new OAuth2ClientInfo();
31 - client.setName(clientRegistration.getLoginButtonLabel());  
32 - client.setUrl(String.format(OAUTH2_AUTHORIZATION_PATH_TEMPLATE, clientRegistration.getUuidId().toString()));  
33 - client.setIcon(clientRegistration.getLoginButtonIcon()); 28 + client.setName(clientRegistrationInfo.getLoginButtonLabel());
  29 + client.setUrl(String.format(OAUTH2_AUTHORIZATION_PATH_TEMPLATE, clientRegistrationInfo.getUuidId().toString()));
  30 + client.setIcon(clientRegistrationInfo.getLoginButtonIcon());
34 return client; 31 return client;
35 } 32 }
36 33
37 - public static List<OAuth2ClientRegistration> toClientRegistrations(OAuth2ClientsParams oAuth2Params) {  
38 - return oAuth2Params.getOAuth2DomainDtos().stream()  
39 - .flatMap(domainParams -> domainParams.getClientRegistrations().stream()  
40 - .map(clientRegistrationDto -> OAuth2Utils.toClientRegistration(oAuth2Params.isEnabled(),  
41 - domainParams.getDomainName(),  
42 - domainParams.getRedirectUriTemplate(),  
43 - clientRegistrationDto)  
44 - ))  
45 - .collect(Collectors.toList());  
46 - }  
47 -  
48 - public static OAuth2ClientsParams toOAuth2Params(List<OAuth2ClientRegistration> clientRegistrations) {  
49 - Map<String, OAuth2ClientsDomainParams> domainParamsMap = new HashMap<>();  
50 - boolean enabled = true;  
51 - for (OAuth2ClientRegistration clientRegistration : clientRegistrations) {  
52 - enabled = clientRegistration.isEnabled();  
53 - String domainName = clientRegistration.getDomainName();  
54 - OAuth2ClientsDomainParams domainParams = domainParamsMap.computeIfAbsent(domainName,  
55 - key -> new OAuth2ClientsDomainParams(domainName, clientRegistration.getRedirectUriTemplate(), new ArrayList<>())  
56 - );  
57 - domainParams.getClientRegistrations()  
58 - .add(toClientRegistrationDto(clientRegistration)); 34 + public static OAuth2ClientsParams toOAuth2Params(List<ExtendedOAuth2ClientRegistrationInfo> extendedOAuth2ClientRegistrationInfos) {
  35 + Map<OAuth2ClientRegistrationInfoId, Set<DomainInfo>> domainsByInfoId = new HashMap<>();
  36 + Map<OAuth2ClientRegistrationInfoId, OAuth2ClientRegistrationInfo> infoById = new HashMap<>();
  37 + for (ExtendedOAuth2ClientRegistrationInfo extendedClientRegistrationInfo : extendedOAuth2ClientRegistrationInfos) {
  38 + String domainName = extendedClientRegistrationInfo.getDomainName();
  39 + SchemeType domainScheme = extendedClientRegistrationInfo.getDomainScheme();
  40 + domainsByInfoId.computeIfAbsent(extendedClientRegistrationInfo.getId(), key -> new HashSet<>())
  41 + .add(new DomainInfo(domainScheme, domainName));
  42 + infoById.put(extendedClientRegistrationInfo.getId(), extendedClientRegistrationInfo);
59 } 43 }
60 - return new OAuth2ClientsParams(enabled, new ArrayList<>(domainParamsMap.values())); 44 + Map<Set<DomainInfo>, OAuth2ClientsDomainParams> domainParamsMap = new HashMap<>();
  45 + domainsByInfoId.forEach((clientRegistrationInfoId, domainInfos) -> {
  46 + domainParamsMap.computeIfAbsent(domainInfos,
  47 + key -> new OAuth2ClientsDomainParams(key, new HashSet<>())
  48 + )
  49 + .getClientRegistrations()
  50 + .add(toClientRegistrationDto(infoById.get(clientRegistrationInfoId)));
  51 + });
  52 + boolean enabled = extendedOAuth2ClientRegistrationInfos.stream()
  53 + .map(OAuth2ClientRegistrationInfo::isEnabled)
  54 + .findFirst().orElse(false);
  55 + return new OAuth2ClientsParams(enabled, new HashSet<>(domainParamsMap.values()));
61 } 56 }
62 57
63 - public static ClientRegistrationDto toClientRegistrationDto(OAuth2ClientRegistration oAuth2ClientRegistration) { 58 + public static ClientRegistrationDto toClientRegistrationDto(OAuth2ClientRegistrationInfo oAuth2ClientRegistrationInfo) {
64 return ClientRegistrationDto.builder() 59 return ClientRegistrationDto.builder()
65 - .id(oAuth2ClientRegistration.getId())  
66 - .createdTime(oAuth2ClientRegistration.getCreatedTime())  
67 - .mapperConfig(oAuth2ClientRegistration.getMapperConfig())  
68 - .clientId(oAuth2ClientRegistration.getClientId())  
69 - .clientSecret(oAuth2ClientRegistration.getClientSecret())  
70 - .authorizationUri(oAuth2ClientRegistration.getAuthorizationUri())  
71 - .accessTokenUri(oAuth2ClientRegistration.getAccessTokenUri())  
72 - .scope(oAuth2ClientRegistration.getScope())  
73 - .userInfoUri(oAuth2ClientRegistration.getUserInfoUri())  
74 - .userNameAttributeName(oAuth2ClientRegistration.getUserNameAttributeName())  
75 - .jwkSetUri(oAuth2ClientRegistration.getJwkSetUri())  
76 - .clientAuthenticationMethod(oAuth2ClientRegistration.getClientAuthenticationMethod())  
77 - .loginButtonLabel(oAuth2ClientRegistration.getLoginButtonLabel())  
78 - .loginButtonIcon(oAuth2ClientRegistration.getLoginButtonIcon())  
79 - .additionalInfo(oAuth2ClientRegistration.getAdditionalInfo()) 60 + .mapperConfig(oAuth2ClientRegistrationInfo.getMapperConfig())
  61 + .clientId(oAuth2ClientRegistrationInfo.getClientId())
  62 + .clientSecret(oAuth2ClientRegistrationInfo.getClientSecret())
  63 + .authorizationUri(oAuth2ClientRegistrationInfo.getAuthorizationUri())
  64 + .accessTokenUri(oAuth2ClientRegistrationInfo.getAccessTokenUri())
  65 + .scope(oAuth2ClientRegistrationInfo.getScope())
  66 + .userInfoUri(oAuth2ClientRegistrationInfo.getUserInfoUri())
  67 + .userNameAttributeName(oAuth2ClientRegistrationInfo.getUserNameAttributeName())
  68 + .jwkSetUri(oAuth2ClientRegistrationInfo.getJwkSetUri())
  69 + .clientAuthenticationMethod(oAuth2ClientRegistrationInfo.getClientAuthenticationMethod())
  70 + .loginButtonLabel(oAuth2ClientRegistrationInfo.getLoginButtonLabel())
  71 + .loginButtonIcon(oAuth2ClientRegistrationInfo.getLoginButtonIcon())
  72 + .additionalInfo(oAuth2ClientRegistrationInfo.getAdditionalInfo())
80 .build(); 73 .build();
81 } 74 }
82 75
83 - private static OAuth2ClientRegistration toClientRegistration(boolean enabled, String domainName,  
84 - String redirectUriTemplate,  
85 - ClientRegistrationDto clientRegistrationDto) { 76 + public static OAuth2ClientRegistrationInfo toClientRegistrationInfo(boolean enabled, ClientRegistrationDto clientRegistrationDto) {
  77 + OAuth2ClientRegistrationInfo clientRegistrationInfo = new OAuth2ClientRegistrationInfo();
  78 + clientRegistrationInfo.setEnabled(enabled);
  79 + clientRegistrationInfo.setMapperConfig(clientRegistrationDto.getMapperConfig());
  80 + clientRegistrationInfo.setClientId(clientRegistrationDto.getClientId());
  81 + clientRegistrationInfo.setClientSecret(clientRegistrationDto.getClientSecret());
  82 + clientRegistrationInfo.setAuthorizationUri(clientRegistrationDto.getAuthorizationUri());
  83 + clientRegistrationInfo.setAccessTokenUri(clientRegistrationDto.getAccessTokenUri());
  84 + clientRegistrationInfo.setScope(clientRegistrationDto.getScope());
  85 + clientRegistrationInfo.setUserInfoUri(clientRegistrationDto.getUserInfoUri());
  86 + clientRegistrationInfo.setUserNameAttributeName(clientRegistrationDto.getUserNameAttributeName());
  87 + clientRegistrationInfo.setJwkSetUri(clientRegistrationDto.getJwkSetUri());
  88 + clientRegistrationInfo.setClientAuthenticationMethod(clientRegistrationDto.getClientAuthenticationMethod());
  89 + clientRegistrationInfo.setLoginButtonLabel(clientRegistrationDto.getLoginButtonLabel());
  90 + clientRegistrationInfo.setLoginButtonIcon(clientRegistrationDto.getLoginButtonIcon());
  91 + clientRegistrationInfo.setAdditionalInfo(clientRegistrationDto.getAdditionalInfo());
  92 + return clientRegistrationInfo;
  93 + }
  94 +
  95 + public static OAuth2ClientRegistration toClientRegistration(OAuth2ClientRegistrationInfoId clientRegistrationInfoId, SchemeType domainScheme, String domainName) {
86 OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration(); 96 OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration();
87 - clientRegistration.setId(clientRegistrationDto.getId());  
88 - clientRegistration.setEnabled(enabled);  
89 - clientRegistration.setCreatedTime(clientRegistrationDto.getCreatedTime()); 97 + clientRegistration.setClientRegistrationId(clientRegistrationInfoId);
90 clientRegistration.setDomainName(domainName); 98 clientRegistration.setDomainName(domainName);
91 - clientRegistration.setRedirectUriTemplate(redirectUriTemplate);  
92 - clientRegistration.setMapperConfig(clientRegistrationDto.getMapperConfig());  
93 - clientRegistration.setClientId(clientRegistrationDto.getClientId());  
94 - clientRegistration.setClientSecret(clientRegistrationDto.getClientSecret());  
95 - clientRegistration.setAuthorizationUri(clientRegistrationDto.getAuthorizationUri());  
96 - clientRegistration.setAccessTokenUri(clientRegistrationDto.getAccessTokenUri());  
97 - clientRegistration.setScope(clientRegistrationDto.getScope());  
98 - clientRegistration.setUserInfoUri(clientRegistrationDto.getUserInfoUri());  
99 - clientRegistration.setUserNameAttributeName(clientRegistrationDto.getUserNameAttributeName());  
100 - clientRegistration.setJwkSetUri(clientRegistrationDto.getJwkSetUri());  
101 - clientRegistration.setClientAuthenticationMethod(clientRegistrationDto.getClientAuthenticationMethod());  
102 - clientRegistration.setLoginButtonLabel(clientRegistrationDto.getLoginButtonLabel());  
103 - clientRegistration.setLoginButtonIcon(clientRegistrationDto.getLoginButtonIcon());  
104 - clientRegistration.setAdditionalInfo(clientRegistrationDto.getAdditionalInfo()); 99 + clientRegistration.setDomainScheme(domainScheme);
105 return clientRegistration; 100 return clientRegistration;
106 } 101 }
107 } 102 }
@@ -16,18 +16,15 @@ @@ -16,18 +16,15 @@
16 package org.thingsboard.server.dao.sql.oauth2; 16 package org.thingsboard.server.dao.sql.oauth2;
17 17
18 import lombok.RequiredArgsConstructor; 18 import lombok.RequiredArgsConstructor;
  19 +import lombok.extern.slf4j.Slf4j;
19 import org.springframework.data.repository.CrudRepository; 20 import org.springframework.data.repository.CrudRepository;
20 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
21 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; 22 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration;
22 -import org.thingsboard.server.dao.DaoUtil;  
23 import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity; 23 import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity;
24 import org.thingsboard.server.dao.oauth2.OAuth2ClientRegistrationDao; 24 import org.thingsboard.server.dao.oauth2.OAuth2ClientRegistrationDao;
25 import org.thingsboard.server.dao.sql.JpaAbstractDao; 25 import org.thingsboard.server.dao.sql.JpaAbstractDao;
26 26
27 -import java.util.ArrayList;  
28 -import java.util.List;  
29 import java.util.UUID; 27 import java.util.UUID;
30 -import java.util.stream.Collectors;  
31 28
32 @Component 29 @Component
33 @RequiredArgsConstructor 30 @RequiredArgsConstructor
@@ -45,23 +42,7 @@ public class JpaOAuth2ClientRegistrationDao extends JpaAbstractDao<OAuth2ClientR @@ -45,23 +42,7 @@ public class JpaOAuth2ClientRegistrationDao extends JpaAbstractDao<OAuth2ClientR
45 } 42 }
46 43
47 @Override 44 @Override
48 - public List<OAuth2ClientRegistration> findAll() {  
49 - Iterable<OAuth2ClientRegistrationEntity> entities = repository.findAll();  
50 - List<OAuth2ClientRegistration> result = new ArrayList<>();  
51 - entities.forEach(entity -> {  
52 - result.add(DaoUtil.getData(entity));  
53 - });  
54 - return result;  
55 - }  
56 -  
57 - @Override  
58 - public List<OAuth2ClientRegistration> findByDomainName(String domainName) {  
59 - List<OAuth2ClientRegistrationEntity> entities = repository.findAllByDomainName(domainName);  
60 - return entities.stream().map(DaoUtil::getData).collect(Collectors.toList());  
61 - }  
62 -  
63 - @Override  
64 - public int removeByDomainName(String domainName) {  
65 - return repository.deleteByDomainName(domainName); 45 + public void deleteAll() {
  46 + repository.deleteAll();
66 } 47 }
67 } 48 }
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.sql.oauth2;
  17 +
  18 +import lombok.RequiredArgsConstructor;
  19 +import org.springframework.data.repository.CrudRepository;
  20 +import org.springframework.stereotype.Component;
  21 +import org.thingsboard.server.common.data.oauth2.ExtendedOAuth2ClientRegistrationInfo;
  22 +import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationInfo;
  23 +import org.thingsboard.server.common.data.oauth2.SchemeType;
  24 +import org.thingsboard.server.dao.DaoUtil;
  25 +import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationInfoEntity;
  26 +import org.thingsboard.server.dao.oauth2.OAuth2ClientRegistrationInfoDao;
  27 +import org.thingsboard.server.dao.sql.JpaAbstractDao;
  28 +
  29 +import java.util.ArrayList;
  30 +import java.util.List;
  31 +import java.util.UUID;
  32 +import java.util.stream.Collectors;
  33 +
  34 +@Component
  35 +@RequiredArgsConstructor
  36 +public class JpaOAuth2ClientRegistrationInfoDao extends JpaAbstractDao<OAuth2ClientRegistrationInfoEntity, OAuth2ClientRegistrationInfo> implements OAuth2ClientRegistrationInfoDao {
  37 + private final OAuth2ClientRegistrationInfoRepository repository;
  38 +
  39 + @Override
  40 + protected Class<OAuth2ClientRegistrationInfoEntity> getEntityClass() {
  41 + return OAuth2ClientRegistrationInfoEntity.class;
  42 + }
  43 +
  44 + @Override
  45 + protected CrudRepository<OAuth2ClientRegistrationInfoEntity, UUID> getCrudRepository() {
  46 + return repository;
  47 + }
  48 +
  49 + @Override
  50 + public List<OAuth2ClientRegistrationInfo> findAll() {
  51 + Iterable<OAuth2ClientRegistrationInfoEntity> entities = repository.findAll();
  52 + List<OAuth2ClientRegistrationInfo> result = new ArrayList<>();
  53 + entities.forEach(entity -> {
  54 + result.add(DaoUtil.getData(entity));
  55 + });
  56 + return result;
  57 + }
  58 +
  59 + @Override
  60 + public List<ExtendedOAuth2ClientRegistrationInfo> findAllExtended() {
  61 + return repository.findAllExtended().stream()
  62 + .map(DaoUtil::getData)
  63 + .collect(Collectors.toList());
  64 + }
  65 +
  66 + @Override
  67 + public List<OAuth2ClientRegistrationInfo> findByDomainSchemesAndDomainName(List<SchemeType> domainSchemes, String domainName) {
  68 + List<OAuth2ClientRegistrationInfoEntity> entities = repository.findAllByDomainSchemesAndName(domainSchemes, domainName);
  69 + return entities.stream().map(DaoUtil::getData).collect(Collectors.toList());
  70 + }
  71 +
  72 + @Override
  73 + public void deleteAll() {
  74 + repository.deleteAll();
  75 + }
  76 +}
  1 +/**
  2 + * Copyright © 2016-2020 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.dao.sql.oauth2;
  17 +
  18 +import org.springframework.data.jpa.repository.Query;
  19 +import org.springframework.data.repository.CrudRepository;
  20 +import org.springframework.data.repository.query.Param;
  21 +import org.thingsboard.server.common.data.oauth2.SchemeType;
  22 +import org.thingsboard.server.dao.model.sql.ExtendedOAuth2ClientRegistrationInfoEntity;
  23 +import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationInfoEntity;
  24 +
  25 +import java.util.List;
  26 +import java.util.UUID;
  27 +
  28 +public interface OAuth2ClientRegistrationInfoRepository extends CrudRepository<OAuth2ClientRegistrationInfoEntity, UUID> {
  29 + @Query("SELECT new OAuth2ClientRegistrationInfoEntity(cr_info) " +
  30 + "FROM OAuth2ClientRegistrationInfoEntity cr_info " +
  31 + "LEFT JOIN OAuth2ClientRegistrationEntity cr on cr_info.id = cr.clientRegistrationInfoId " +
  32 + "WHERE cr.domainName = :domainName " +
  33 + "AND cr.domainScheme IN (:domainSchemes)")
  34 + List<OAuth2ClientRegistrationInfoEntity> findAllByDomainSchemesAndName(@Param("domainSchemes") List<SchemeType> domainSchemes,
  35 + @Param("domainName") String domainName);
  36 +
  37 + @Query("SELECT new org.thingsboard.server.dao.model.sql.ExtendedOAuth2ClientRegistrationInfoEntity(cr_info, cr.domainName, cr.domainScheme) " +
  38 + "FROM OAuth2ClientRegistrationInfoEntity cr_info " +
  39 + "LEFT JOIN OAuth2ClientRegistrationEntity cr on cr_info.id = cr.clientRegistrationInfoId ")
  40 + List<ExtendedOAuth2ClientRegistrationInfoEntity> findAllExtended();
  41 +}
@@ -18,11 +18,7 @@ package org.thingsboard.server.dao.sql.oauth2; @@ -18,11 +18,7 @@ package org.thingsboard.server.dao.sql.oauth2;
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity; 19 import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity;
20 20
21 -import java.util.List;  
22 import java.util.UUID; 21 import java.util.UUID;
23 22
24 public interface OAuth2ClientRegistrationRepository extends CrudRepository<OAuth2ClientRegistrationEntity, UUID> { 23 public interface OAuth2ClientRegistrationRepository extends CrudRepository<OAuth2ClientRegistrationEntity, UUID> {
25 - List<OAuth2ClientRegistrationEntity> findAllByDomainName(String domainName);  
26 -  
27 - int deleteByDomainName(String domainName);  
28 } 24 }
@@ -291,17 +291,15 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary ( @@ -291,17 +291,15 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
291 ); 291 );
292 292
293 293
294 -CREATE TABLE IF NOT EXISTS oauth2_client_registration (  
295 - id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY, 294 +CREATE TABLE IF NOT EXISTS oauth2_client_registration_info (
  295 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_info_pkey PRIMARY KEY,
296 enabled boolean, 296 enabled boolean,
297 created_time bigint NOT NULL, 297 created_time bigint NOT NULL,
298 additional_info varchar, 298 additional_info varchar,
299 - domain_name varchar(255),  
300 client_id varchar(255), 299 client_id varchar(255),
301 client_secret varchar(255), 300 client_secret varchar(255),
302 authorization_uri varchar(255), 301 authorization_uri varchar(255),
303 token_uri varchar(255), 302 token_uri varchar(255),
304 - redirect_uri_template varchar(255),  
305 scope varchar(255), 303 scope varchar(255),
306 user_info_uri varchar(255), 304 user_info_uri varchar(255),
307 user_name_attribute_name varchar(255), 305 user_name_attribute_name varchar(255),
@@ -326,6 +324,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( @@ -326,6 +324,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration (
326 custom_send_token boolean 324 custom_send_token boolean
327 ); 325 );
328 326
  327 +CREATE TABLE IF NOT EXISTS oauth2_client_registration (
  328 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY,
  329 + created_time bigint NOT NULL,
  330 + domain_name varchar(255),
  331 + domain_scheme varchar(31),
  332 + client_registration_info_id uuid
  333 +);
  334 +
329 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( 335 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template (
330 id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY, 336 id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY,
331 created_time bigint NOT NULL, 337 created_time bigint NOT NULL,
@@ -316,17 +316,15 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary @@ -316,17 +316,15 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary
316 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) 316 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
317 ); 317 );
318 318
319 -CREATE TABLE IF NOT EXISTS oauth2_client_registration (  
320 - id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY, 319 +CREATE TABLE IF NOT EXISTS oauth2_client_registration_info (
  320 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_info_pkey PRIMARY KEY,
321 enabled boolean, 321 enabled boolean,
322 created_time bigint NOT NULL, 322 created_time bigint NOT NULL,
323 additional_info varchar, 323 additional_info varchar,
324 - domain_name varchar(255),  
325 client_id varchar(255), 324 client_id varchar(255),
326 client_secret varchar(255), 325 client_secret varchar(255),
327 authorization_uri varchar(255), 326 authorization_uri varchar(255),
328 token_uri varchar(255), 327 token_uri varchar(255),
329 - redirect_uri_template varchar(255),  
330 scope varchar(255), 328 scope varchar(255),
331 user_info_uri varchar(255), 329 user_info_uri varchar(255),
332 user_name_attribute_name varchar(255), 330 user_name_attribute_name varchar(255),
@@ -351,6 +349,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( @@ -351,6 +349,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration (
351 custom_send_token boolean 349 custom_send_token boolean
352 ); 350 );
353 351
  352 +CREATE TABLE IF NOT EXISTS oauth2_client_registration (
  353 + id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY,
  354 + created_time bigint NOT NULL,
  355 + domain_name varchar(255),
  356 + domain_scheme varchar(31),
  357 + client_registration_info_id uuid
  358 +);
  359 +
354 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( 360 CREATE TABLE IF NOT EXISTS oauth2_client_registration_template (
355 id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY, 361 id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY,
356 created_time bigint NOT NULL, 362 created_time bigint NOT NULL,
@@ -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.google.common.collect.Sets;
18 import org.junit.After; 19 import org.junit.After;
19 import org.junit.Assert; 20 import org.junit.Assert;
20 import org.junit.Before; 21 import org.junit.Before;
@@ -22,170 +23,413 @@ import org.junit.Test; @@ -22,170 +23,413 @@ import org.junit.Test;
22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
23 import org.thingsboard.server.common.data.oauth2.*; 24 import org.thingsboard.server.common.data.oauth2.*;
24 import org.thingsboard.server.dao.oauth2.OAuth2Service; 25 import org.thingsboard.server.dao.oauth2.OAuth2Service;
25 -import org.thingsboard.server.dao.oauth2.OAuth2Utils;  
26 26
27 import java.util.*; 27 import java.util.*;
28 import java.util.stream.Collectors; 28 import java.util.stream.Collectors;
29 29
30 -import static org.thingsboard.server.dao.oauth2.OAuth2Utils.toClientRegistrations;  
31 -  
32 public class BaseOAuth2ServiceTest extends AbstractServiceTest { 30 public class BaseOAuth2ServiceTest extends AbstractServiceTest {
  31 + private static final OAuth2ClientsParams EMPTY_PARAMS = new OAuth2ClientsParams(false, new HashSet<>());
33 32
34 @Autowired 33 @Autowired
35 protected OAuth2Service oAuth2Service; 34 protected OAuth2Service oAuth2Service;
36 35
37 @Before 36 @Before
38 public void beforeRun() { 37 public void beforeRun() {
39 - Assert.assertTrue(oAuth2Service.findAllClientRegistrations().isEmpty()); 38 + Assert.assertTrue(oAuth2Service.findAllClientRegistrationInfos().isEmpty());
40 } 39 }
41 40
42 @After 41 @After
43 public void after() { 42 public void after() {
44 - oAuth2Service.findAllClientRegistrations().forEach(clientRegistration -> {  
45 - oAuth2Service.deleteClientRegistrationById(clientRegistration.getId());  
46 - });  
47 - Assert.assertTrue(oAuth2Service.findAllClientRegistrations().isEmpty()); 43 + oAuth2Service.saveOAuth2Params(EMPTY_PARAMS);
  44 + Assert.assertTrue(oAuth2Service.findAllClientRegistrationInfos().isEmpty());
  45 + Assert.assertTrue(oAuth2Service.findOAuth2Params().getOAuth2DomainDtos().isEmpty());
  46 + }
  47 +
  48 + @Test
  49 + public void testCreateAndFindParams() {
  50 + OAuth2ClientsParams clientsParams = createDefaultClientsParams();
  51 + oAuth2Service.saveOAuth2Params(clientsParams);
  52 + OAuth2ClientsParams foundClientsParams = oAuth2Service.findOAuth2Params();
  53 + Assert.assertNotNull(foundClientsParams);
  54 + // TODO ask if it's safe to check equality on AdditionalProperties
  55 + Assert.assertEquals(clientsParams, foundClientsParams);
48 } 56 }
49 57
50 @Test 58 @Test
51 - public void testCreateNewParams() {  
52 - OAuth2ClientRegistration clientRegistration = validClientRegistration("domain-name");  
53 - OAuth2ClientsParams savedOAuth2Params = oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(clientRegistration)));  
54 - Assert.assertNotNull(savedOAuth2Params); 59 + public void testDisableParams() {
  60 + OAuth2ClientsParams clientsParams = createDefaultClientsParams();
  61 + clientsParams.setEnabled(true);
  62 + oAuth2Service.saveOAuth2Params(clientsParams);
  63 + OAuth2ClientsParams foundClientsParams = oAuth2Service.findOAuth2Params();
  64 + Assert.assertNotNull(foundClientsParams);
  65 + Assert.assertEquals(clientsParams, foundClientsParams);
55 66
56 - List<OAuth2ClientRegistration> savedClientRegistrations = OAuth2Utils.toClientRegistrations(savedOAuth2Params);  
57 - Assert.assertEquals(1, savedClientRegistrations.size()); 67 + clientsParams.setEnabled(false);
  68 + oAuth2Service.saveOAuth2Params(clientsParams);
  69 + OAuth2ClientsParams foundDisabledClientsParams = oAuth2Service.findOAuth2Params();
  70 + Assert.assertEquals(clientsParams, foundDisabledClientsParams);
  71 + }
58 72
59 - OAuth2ClientRegistration savedClientRegistration = savedClientRegistrations.get(0);  
60 - Assert.assertNotNull(savedClientRegistration.getId());  
61 - clientRegistration.setId(savedClientRegistration.getId());  
62 - clientRegistration.setCreatedTime(savedClientRegistration.getCreatedTime());  
63 - Assert.assertEquals(clientRegistration, savedClientRegistration); 73 + @Test
  74 + public void testClearDomainParams() {
  75 + OAuth2ClientsParams clientsParams = createDefaultClientsParams();
  76 + oAuth2Service.saveOAuth2Params(clientsParams);
  77 + OAuth2ClientsParams foundClientsParams = oAuth2Service.findOAuth2Params();
  78 + Assert.assertNotNull(foundClientsParams);
  79 + Assert.assertEquals(clientsParams, foundClientsParams);
64 80
65 - oAuth2Service.deleteClientRegistrationsByDomain("domain-name"); 81 + oAuth2Service.saveOAuth2Params(EMPTY_PARAMS);
  82 + OAuth2ClientsParams foundAfterClearClientsParams = oAuth2Service.findOAuth2Params();
  83 + Assert.assertNotNull(foundAfterClearClientsParams);
  84 + Assert.assertEquals(EMPTY_PARAMS, foundAfterClearClientsParams);
66 } 85 }
67 86
68 @Test 87 @Test
69 - public void testFindDomainParams() {  
70 - OAuth2ClientRegistration clientRegistration = validClientRegistration();  
71 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(clientRegistration)));  
72 -  
73 - OAuth2ClientsParams foundOAuth2Params = oAuth2Service.findOAuth2Params();  
74 - Assert.assertEquals(1, foundOAuth2Params.getOAuth2DomainDtos().size());  
75 - Assert.assertEquals(1, oAuth2Service.findAllClientRegistrations().size());  
76 -  
77 - List<OAuth2ClientRegistration> foundClientRegistrations = OAuth2Utils.toClientRegistrations(foundOAuth2Params);  
78 - OAuth2ClientRegistration foundClientRegistration = foundClientRegistrations.get(0);  
79 - Assert.assertNotNull(foundClientRegistration);  
80 - clientRegistration.setId(foundClientRegistration.getId());  
81 - clientRegistration.setCreatedTime(foundClientRegistration.getCreatedTime());  
82 - Assert.assertEquals(clientRegistration, foundClientRegistration); 88 + public void testUpdateClientsParams() {
  89 + OAuth2ClientsParams clientsParams = createDefaultClientsParams();
  90 + oAuth2Service.saveOAuth2Params(clientsParams);
  91 + OAuth2ClientsParams foundClientsParams = oAuth2Service.findOAuth2Params();
  92 + Assert.assertNotNull(foundClientsParams);
  93 + Assert.assertEquals(clientsParams, foundClientsParams);
  94 +
  95 + OAuth2ClientsParams newClientsParams = new OAuth2ClientsParams(true, Sets.newHashSet(
  96 + OAuth2ClientsDomainParams.builder()
  97 + .domainInfos(Sets.newHashSet(
  98 + DomainInfo.builder().name("another-domain").scheme(SchemeType.HTTPS).build()
  99 + ))
  100 + .clientRegistrations(Sets.newHashSet(
  101 + validClientRegistrationDto()
  102 + ))
  103 + .build(),
  104 + OAuth2ClientsDomainParams.builder()
  105 + .domainInfos(Sets.newHashSet(
  106 + DomainInfo.builder().name("test-domain").scheme(SchemeType.MIXED).build()
  107 + ))
  108 + .clientRegistrations(Sets.newHashSet(
  109 + validClientRegistrationDto()
  110 + ))
  111 + .build()
  112 + ));
  113 + oAuth2Service.saveOAuth2Params(newClientsParams);
  114 + OAuth2ClientsParams foundAfterUpdateClientsParams = oAuth2Service.findOAuth2Params();
  115 + Assert.assertNotNull(foundAfterUpdateClientsParams);
  116 + Assert.assertEquals(newClientsParams, foundAfterUpdateClientsParams);
83 } 117 }
84 118
85 @Test 119 @Test
86 public void testGetOAuth2Clients() { 120 public void testGetOAuth2Clients() {
87 - String testDomainName = "test_domain";  
88 - OAuth2ClientRegistration first = validClientRegistration(testDomainName);  
89 - first.setEnabled(true);  
90 - OAuth2ClientRegistration second = validClientRegistration(testDomainName);  
91 - second.setEnabled(true); 121 + Set<ClientRegistrationDto> firstGroup = Sets.newHashSet(
  122 + validClientRegistrationDto(),
  123 + validClientRegistrationDto(),
  124 + validClientRegistrationDto(),
  125 + validClientRegistrationDto()
  126 + );
  127 + Set<ClientRegistrationDto> secondGroup = Sets.newHashSet(
  128 + validClientRegistrationDto(),
  129 + validClientRegistrationDto()
  130 + );
  131 + Set<ClientRegistrationDto> thirdGroup = Sets.newHashSet(
  132 + validClientRegistrationDto()
  133 + );
  134 + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet(
  135 + OAuth2ClientsDomainParams.builder()
  136 + .domainInfos(Sets.newHashSet(
  137 + DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
  138 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  139 + DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
  140 + ))
  141 + .clientRegistrations(firstGroup)
  142 + .build(),
  143 + OAuth2ClientsDomainParams.builder()
  144 + .domainInfos(Sets.newHashSet(
  145 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
  146 + DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
  147 + ))
  148 + .clientRegistrations(secondGroup)
  149 + .build(),
  150 + OAuth2ClientsDomainParams.builder()
  151 + .domainInfos(Sets.newHashSet(
  152 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
  153 + DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
  154 + ))
  155 + .clientRegistrations(thirdGroup)
  156 + .build()
  157 + ));
  158 +
  159 + oAuth2Service.saveOAuth2Params(clientsParams);
  160 + OAuth2ClientsParams foundClientsParams = oAuth2Service.findOAuth2Params();
  161 + Assert.assertNotNull(foundClientsParams);
  162 + Assert.assertEquals(clientsParams, foundClientsParams);
  163 +
  164 + List<OAuth2ClientInfo> firstGroupClientInfos = firstGroup.stream()
  165 + .map(clientRegistrationDto -> new OAuth2ClientInfo(
  166 + clientRegistrationDto.getLoginButtonLabel(), clientRegistrationDto.getLoginButtonIcon(), null))
  167 + .collect(Collectors.toList());
  168 + List<OAuth2ClientInfo> secondGroupClientInfos = secondGroup.stream()
  169 + .map(clientRegistrationDto -> new OAuth2ClientInfo(
  170 + clientRegistrationDto.getLoginButtonLabel(), clientRegistrationDto.getLoginButtonIcon(), null))
  171 + .collect(Collectors.toList());
  172 + List<OAuth2ClientInfo> thirdGroupClientInfos = thirdGroup.stream()
  173 + .map(clientRegistrationDto -> new OAuth2ClientInfo(
  174 + clientRegistrationDto.getLoginButtonLabel(), clientRegistrationDto.getLoginButtonIcon(), null))
  175 + .collect(Collectors.toList());
92 176
93 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(first)));  
94 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(second))); 177 + List<OAuth2ClientInfo> nonExistentDomainClients = oAuth2Service.getOAuth2Clients("http", "non-existent-domain");
  178 + Assert.assertTrue(nonExistentDomainClients.isEmpty());
95 179
96 - List<OAuth2ClientInfo> oAuth2Clients = oAuth2Service.getOAuth2Clients(testDomainName); 180 + List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain");
  181 + Assert.assertEquals(firstDomainHttpClients.size(), firstDomainHttpClients.size());
  182 + firstGroupClientInfos.forEach(firstGroupClientInfo -> {
  183 + Assert.assertTrue(
  184 + firstDomainHttpClients.stream().anyMatch(clientInfo ->
  185 + clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
  186 + && clientInfo.getName().equals(firstGroupClientInfo.getName()))
  187 + );
  188 + });
97 189
98 - Set<String> actualLabels = new HashSet<>(Arrays.asList(first.getLoginButtonLabel(),  
99 - second.getLoginButtonLabel())); 190 + List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain");
  191 + Assert.assertTrue(firstDomainHttpsClients.isEmpty());
100 192
101 - Set<String> foundLabels = oAuth2Clients.stream().map(OAuth2ClientInfo::getName).collect(Collectors.toSet());  
102 - Assert.assertEquals(actualLabels, foundLabels); 193 + List<OAuth2ClientInfo> fourthDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "fourth-domain");
  194 + Assert.assertEquals(fourthDomainHttpClients.size(), secondGroupClientInfos.size());
  195 + secondGroupClientInfos.forEach(secondGroupClientInfo -> {
  196 + Assert.assertTrue(
  197 + fourthDomainHttpClients.stream().anyMatch(clientInfo ->
  198 + clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
  199 + && clientInfo.getName().equals(secondGroupClientInfo.getName()))
  200 + );
  201 + });
  202 + List<OAuth2ClientInfo> fourthDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "fourth-domain");
  203 + Assert.assertEquals(fourthDomainHttpsClients.size(), secondGroupClientInfos.size());
  204 + secondGroupClientInfos.forEach(secondGroupClientInfo -> {
  205 + Assert.assertTrue(
  206 + fourthDomainHttpsClients.stream().anyMatch(clientInfo ->
  207 + clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
  208 + && clientInfo.getName().equals(secondGroupClientInfo.getName()))
  209 + );
  210 + });
  211 +
  212 + List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain");
  213 + Assert.assertEquals(secondDomainHttpClients.size(), firstGroupClientInfos.size() + secondGroupClientInfos.size());
  214 + firstGroupClientInfos.forEach(firstGroupClientInfo -> {
  215 + Assert.assertTrue(
  216 + secondDomainHttpClients.stream().anyMatch(clientInfo ->
  217 + clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
  218 + && clientInfo.getName().equals(firstGroupClientInfo.getName()))
  219 + );
  220 + });
  221 + secondGroupClientInfos.forEach(secondGroupClientInfo -> {
  222 + Assert.assertTrue(
  223 + secondDomainHttpClients.stream().anyMatch(clientInfo ->
  224 + clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
  225 + && clientInfo.getName().equals(secondGroupClientInfo.getName()))
  226 + );
  227 + });
  228 +
  229 + List<OAuth2ClientInfo> secondDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "second-domain");
  230 + Assert.assertEquals(secondDomainHttpsClients.size(), firstGroupClientInfos.size() + thirdGroupClientInfos.size());
  231 + firstGroupClientInfos.forEach(firstGroupClientInfo -> {
  232 + Assert.assertTrue(
  233 + secondDomainHttpsClients.stream().anyMatch(clientInfo ->
  234 + clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
  235 + && clientInfo.getName().equals(firstGroupClientInfo.getName()))
  236 + );
  237 + });
  238 + thirdGroupClientInfos.forEach(thirdGroupClientInfo -> {
  239 + Assert.assertTrue(
  240 + secondDomainHttpsClients.stream().anyMatch(clientInfo ->
  241 + clientInfo.getIcon().equals(thirdGroupClientInfo.getIcon())
  242 + && clientInfo.getName().equals(thirdGroupClientInfo.getName()))
  243 + );
  244 + });
103 } 245 }
104 246
105 @Test 247 @Test
106 - public void testGetEmptyOAuth2Clients() {  
107 - String testDomainName = "test_domain";  
108 - OAuth2ClientRegistration tenantClientRegistration = validClientRegistration(testDomainName);  
109 - OAuth2ClientRegistration sysAdminClientRegistration = validClientRegistration(testDomainName);  
110 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(tenantClientRegistration)));  
111 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Collections.singletonList(sysAdminClientRegistration)));  
112 - List<OAuth2ClientInfo> oAuth2Clients = oAuth2Service.getOAuth2Clients("random-domain");  
113 - Assert.assertTrue(oAuth2Clients.isEmpty()); 248 + public void testGetDisabledOAuth2Clients() {
  249 + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet(
  250 + OAuth2ClientsDomainParams.builder()
  251 + .domainInfos(Sets.newHashSet(
  252 + DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
  253 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  254 + DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
  255 + ))
  256 + .clientRegistrations(Sets.newHashSet(
  257 + validClientRegistrationDto(),
  258 + validClientRegistrationDto(),
  259 + validClientRegistrationDto()
  260 + ))
  261 + .build(),
  262 + OAuth2ClientsDomainParams.builder()
  263 + .domainInfos(Sets.newHashSet(
  264 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
  265 + DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
  266 + ))
  267 + .clientRegistrations(Sets.newHashSet(
  268 + validClientRegistrationDto(),
  269 + validClientRegistrationDto()
  270 + ))
  271 + .build()
  272 + ));
  273 +
  274 + oAuth2Service.saveOAuth2Params(clientsParams);
  275 +
  276 + List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain");
  277 + Assert.assertEquals(5, secondDomainHttpClients.size());
  278 +
  279 + clientsParams.setEnabled(false);
  280 + oAuth2Service.saveOAuth2Params(clientsParams);
  281 +
  282 + List<OAuth2ClientInfo> secondDomainHttpDisabledClients = oAuth2Service.getOAuth2Clients("http", "second-domain");
  283 + Assert.assertEquals(0, secondDomainHttpDisabledClients.size());
114 } 284 }
115 285
116 @Test 286 @Test
117 - public void testDeleteOAuth2ClientRegistration() {  
118 - OAuth2ClientRegistration first = validClientRegistration();  
119 - OAuth2ClientRegistration second = validClientRegistration();  
120 -  
121 - OAuth2ClientsParams savedFirstOAuth2Params = oAuth2Service.saveOAuth2Params(  
122 - OAuth2Utils.toOAuth2Params(Collections.singletonList(first)));  
123 - OAuth2ClientsParams savedSecondOAuth2Params = oAuth2Service.saveOAuth2Params(  
124 - OAuth2Utils.toOAuth2Params(Collections.singletonList(second)));  
125 -  
126 - OAuth2ClientRegistration savedFirstRegistration = toClientRegistrations(savedFirstOAuth2Params).get(0);  
127 - OAuth2ClientRegistration savedSecondRegistration = toClientRegistrations(savedSecondOAuth2Params).get(0);  
128 -  
129 - oAuth2Service.deleteClientRegistrationById(savedFirstRegistration.getId());  
130 - List<OAuth2ClientRegistration> foundRegistrations = oAuth2Service.findAllClientRegistrations();  
131 - Assert.assertEquals(1, foundRegistrations.size());  
132 - Assert.assertEquals(savedSecondRegistration, foundRegistrations.get(0)); 287 + public void testFindAllClientRegistrationInfos() {
  288 + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet(
  289 + OAuth2ClientsDomainParams.builder()
  290 + .domainInfos(Sets.newHashSet(
  291 + DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
  292 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  293 + DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
  294 + ))
  295 + .clientRegistrations(Sets.newHashSet(
  296 + validClientRegistrationDto(),
  297 + validClientRegistrationDto(),
  298 + validClientRegistrationDto()
  299 + ))
  300 + .build(),
  301 + OAuth2ClientsDomainParams.builder()
  302 + .domainInfos(Sets.newHashSet(
  303 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
  304 + DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
  305 + ))
  306 + .clientRegistrations(Sets.newHashSet(
  307 + validClientRegistrationDto(),
  308 + validClientRegistrationDto()
  309 + ))
  310 + .build(),
  311 + OAuth2ClientsDomainParams.builder()
  312 + .domainInfos(Sets.newHashSet(
  313 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
  314 + DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
  315 + ))
  316 + .clientRegistrations(Sets.newHashSet(
  317 + validClientRegistrationDto()
  318 + ))
  319 + .build()
  320 + ));
  321 +
  322 + oAuth2Service.saveOAuth2Params(clientsParams);
  323 + List<OAuth2ClientRegistrationInfo> foundClientRegistrationInfos = oAuth2Service.findAllClientRegistrationInfos();
  324 + Assert.assertEquals(6, foundClientRegistrationInfos.size());
  325 + clientsParams.getOAuth2DomainDtos().stream()
  326 + .flatMap(domainParams -> domainParams.getClientRegistrations().stream())
  327 + .forEach(clientRegistrationDto ->
  328 + Assert.assertTrue(
  329 + foundClientRegistrationInfos.stream()
  330 + .anyMatch(clientRegistrationInfo -> clientRegistrationInfo.getClientId().equals(clientRegistrationDto.getClientId()))
  331 + )
  332 + );
133 } 333 }
134 334
135 @Test 335 @Test
136 - public void testDeleteDomainOAuth2ClientRegistrations() {  
137 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Arrays.asList(  
138 - validClientRegistration("domain1"),  
139 - validClientRegistration("domain1"),  
140 - validClientRegistration("domain2")  
141 - )));  
142 - oAuth2Service.saveOAuth2Params(OAuth2Utils.toOAuth2Params(Arrays.asList(  
143 - validClientRegistration("domain2")  
144 - )));  
145 - Assert.assertEquals(4, oAuth2Service.findAllClientRegistrations().size());  
146 - OAuth2ClientsParams oAuth2Params = oAuth2Service.findOAuth2Params();  
147 - List<OAuth2ClientRegistration> clientRegistrations = toClientRegistrations(oAuth2Params);  
148 - Assert.assertEquals(2, oAuth2Params.getOAuth2DomainDtos().size());  
149 - Assert.assertEquals(4, clientRegistrations.size());  
150 -  
151 - oAuth2Service.deleteClientRegistrationsByDomain("domain1");  
152 - Assert.assertEquals(2, oAuth2Service.findAllClientRegistrations().size());  
153 - Assert.assertEquals(1, oAuth2Service.findOAuth2Params().getOAuth2DomainDtos().size());  
154 - Assert.assertEquals(2, toClientRegistrations(oAuth2Service.findOAuth2Params()).size());  
155 - } 336 + public void testFindClientRegistrationById() {
  337 + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet(
  338 + OAuth2ClientsDomainParams.builder()
  339 + .domainInfos(Sets.newHashSet(
  340 + DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
  341 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  342 + DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
  343 + ))
  344 + .clientRegistrations(Sets.newHashSet(
  345 + validClientRegistrationDto(),
  346 + validClientRegistrationDto(),
  347 + validClientRegistrationDto()
  348 + ))
  349 + .build(),
  350 + OAuth2ClientsDomainParams.builder()
  351 + .domainInfos(Sets.newHashSet(
  352 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
  353 + DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
  354 + ))
  355 + .clientRegistrations(Sets.newHashSet(
  356 + validClientRegistrationDto(),
  357 + validClientRegistrationDto()
  358 + ))
  359 + .build(),
  360 + OAuth2ClientsDomainParams.builder()
  361 + .domainInfos(Sets.newHashSet(
  362 + DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
  363 + DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
  364 + ))
  365 + .clientRegistrations(Sets.newHashSet(
  366 + validClientRegistrationDto()
  367 + ))
  368 + .build()
  369 + ));
156 370
157 - private OAuth2ClientRegistration validClientRegistration() {  
158 - return validClientRegistration(UUID.randomUUID().toString()); 371 + oAuth2Service.saveOAuth2Params(clientsParams);
  372 + List<OAuth2ClientRegistrationInfo> clientRegistrationInfos = oAuth2Service.findAllClientRegistrationInfos();
  373 + clientRegistrationInfos.forEach(clientRegistrationInfo -> {
  374 + OAuth2ClientRegistrationInfo foundClientRegistrationInfo = oAuth2Service.findClientRegistrationInfo(clientRegistrationInfo.getUuidId());
  375 + Assert.assertEquals(clientRegistrationInfo, foundClientRegistrationInfo);
  376 + });
159 } 377 }
160 378
161 - private OAuth2ClientRegistration validClientRegistration(String domainName) {  
162 - OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration();  
163 - clientRegistration.setDomainName(domainName);  
164 - clientRegistration.setMapperConfig(  
165 - OAuth2MapperConfig.builder()  
166 - .allowUserCreation(true)  
167 - .activateUser(true)  
168 - .type(MapperType.CUSTOM)  
169 - .custom(  
170 - OAuth2CustomMapperConfig.builder()  
171 - .url("UUID.randomUUID().toString()")  
172 - .build()  
173 - ) 379 + private OAuth2ClientsParams createDefaultClientsParams() {
  380 + return new OAuth2ClientsParams(true, Sets.newHashSet(
  381 + OAuth2ClientsDomainParams.builder()
  382 + .domainInfos(Sets.newHashSet(
  383 + DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
  384 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  385 + DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
  386 + ))
  387 + .clientRegistrations(Sets.newHashSet(
  388 + validClientRegistrationDto(),
  389 + validClientRegistrationDto(),
  390 + validClientRegistrationDto(),
  391 + validClientRegistrationDto()
  392 + ))
  393 + .build(),
  394 + OAuth2ClientsDomainParams.builder()
  395 + .domainInfos(Sets.newHashSet(
  396 + DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
  397 + DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
  398 + ))
  399 + .clientRegistrations(Sets.newHashSet(
  400 + validClientRegistrationDto(),
  401 + validClientRegistrationDto()
  402 + ))
174 .build() 403 .build()
175 - );  
176 - clientRegistration.setClientId(UUID.randomUUID().toString());  
177 - clientRegistration.setClientSecret(UUID.randomUUID().toString());  
178 - clientRegistration.setAuthorizationUri(UUID.randomUUID().toString());  
179 - clientRegistration.setAccessTokenUri(UUID.randomUUID().toString());  
180 - clientRegistration.setRedirectUriTemplate(UUID.randomUUID().toString());  
181 - clientRegistration.setScope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()));  
182 - clientRegistration.setUserInfoUri(UUID.randomUUID().toString());  
183 - clientRegistration.setUserNameAttributeName(UUID.randomUUID().toString());  
184 - clientRegistration.setJwkSetUri(UUID.randomUUID().toString());  
185 - clientRegistration.setClientAuthenticationMethod(UUID.randomUUID().toString());  
186 - clientRegistration.setLoginButtonLabel(UUID.randomUUID().toString());  
187 - clientRegistration.setLoginButtonIcon(UUID.randomUUID().toString());  
188 - clientRegistration.setAdditionalInfo(mapper.createObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()));  
189 - return clientRegistration; 404 + ));
  405 + }
  406 +
  407 + private ClientRegistrationDto validClientRegistrationDto() {
  408 + return ClientRegistrationDto.builder()
  409 + .clientId(UUID.randomUUID().toString())
  410 + .clientSecret(UUID.randomUUID().toString())
  411 + .authorizationUri(UUID.randomUUID().toString())
  412 + .accessTokenUri(UUID.randomUUID().toString())
  413 + .scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()))
  414 + .userInfoUri(UUID.randomUUID().toString())
  415 + .userNameAttributeName(UUID.randomUUID().toString())
  416 + .jwkSetUri(UUID.randomUUID().toString())
  417 + .clientAuthenticationMethod(UUID.randomUUID().toString())
  418 + .loginButtonLabel(UUID.randomUUID().toString())
  419 + .loginButtonIcon(UUID.randomUUID().toString())
  420 + .additionalInfo(mapper.createObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()))
  421 + .mapperConfig(
  422 + OAuth2MapperConfig.builder()
  423 + .allowUserCreation(true)
  424 + .activateUser(true)
  425 + .type(MapperType.CUSTOM)
  426 + .custom(
  427 + OAuth2CustomMapperConfig.builder()
  428 + .url(UUID.randomUUID().toString())
  429 + .build()
  430 + )
  431 + .build()
  432 + )
  433 + .build();
190 } 434 }
191 } 435 }