Commit c7e236499ecbec5eeb4bac1d2b21f3adaadb334c
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 | 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 | 21 | enabled boolean, |
22 | 22 | created_time bigint NOT NULL, |
23 | 23 | additional_info varchar, |
24 | - domain_name varchar(255), | |
25 | 24 | client_id varchar(255), |
26 | 25 | client_secret varchar(255), |
27 | 26 | authorization_uri varchar(255), |
28 | 27 | token_uri varchar(255), |
29 | - redirect_uri_template varchar(255), | |
30 | 28 | scope varchar(255), |
31 | 29 | user_info_uri varchar(255), |
32 | 30 | user_name_attribute_name varchar(255), |
... | ... | @@ -51,6 +49,16 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( |
51 | 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 | 62 | DROP TABLE IF EXISTS oauth2_client_registration_template; |
55 | 63 | |
56 | 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 | 32 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
33 | 33 | import org.springframework.security.config.http.SessionCreationPolicy; |
34 | 34 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
35 | +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver; | |
35 | 36 | import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
36 | 37 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; |
37 | 38 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
... | ... | @@ -175,6 +176,9 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt |
175 | 176 | web.ignoring().antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**"); |
176 | 177 | } |
177 | 178 | |
179 | + @Autowired | |
180 | + private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver; | |
181 | + | |
178 | 182 | @Override |
179 | 183 | protected void configure(HttpSecurity http) throws Exception { |
180 | 184 | http.headers().cacheControl().and().frameOptions().disable() |
... | ... | @@ -209,6 +213,8 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt |
209 | 213 | .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class); |
210 | 214 | if (oauth2Configuration != null) { |
211 | 215 | http.oauth2Login() |
216 | + .authorizationEndpoint().authorizationRequestResolver(oAuth2AuthorizationRequestResolver) | |
217 | + .and() | |
212 | 218 | .loginPage("/oauth2Login") |
213 | 219 | .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl()) |
214 | 220 | .successHandler(oauth2AuthenticationSuccessHandler) | ... | ... |
... | ... | @@ -373,7 +373,7 @@ public abstract class BaseController { |
373 | 373 | case WIDGET_TYPE: |
374 | 374 | checkWidgetTypeId(new WidgetTypeId(entityId.getId()), operation); |
375 | 375 | return; |
376 | - case OAUTH2_CLIENT_REGISTRATION: | |
376 | + case OAUTH2_CLIENT_REGISTRATION_INFO: | |
377 | 377 | case OAUTH2_CLIENT_REGISTRATION_TEMPLATE: |
378 | 378 | return; |
379 | 379 | default: | ... | ... |
... | ... | @@ -19,13 +19,10 @@ import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.springframework.http.HttpStatus; |
20 | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
21 | 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 | 22 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
25 | -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId; | |
26 | 23 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
27 | -import org.thingsboard.server.common.data.oauth2.OAuth2ClientsDomainParams; | |
28 | 24 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams; |
25 | +import org.thingsboard.server.common.data.oauth2.SchemeType; | |
29 | 26 | import org.thingsboard.server.queue.util.TbCoreComponent; |
30 | 27 | |
31 | 28 | import javax.servlet.http.HttpServletRequest; |
... | ... | @@ -36,14 +33,11 @@ import java.util.List; |
36 | 33 | @RequestMapping("/api") |
37 | 34 | @Slf4j |
38 | 35 | public class OAuth2Controller extends BaseController { |
39 | - private static final String CLIENT_REGISTRATION_ID = "clientRegistrationId"; | |
40 | - private static final String DOMAIN = "domain"; | |
41 | - | |
42 | 36 | @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) |
43 | 37 | @ResponseBody |
44 | 38 | public List<OAuth2ClientInfo> getOAuth2Clients(HttpServletRequest request) throws ThingsboardException { |
45 | 39 | try { |
46 | - return oAuth2Service.getOAuth2Clients(request.getServerName()); | |
40 | + return oAuth2Service.getOAuth2Clients(request.getScheme(), request.getServerName()); | |
47 | 41 | } catch (Exception e) { |
48 | 42 | throw handleException(e); |
49 | 43 | } |
... | ... | @@ -65,56 +59,9 @@ public class OAuth2Controller extends BaseController { |
65 | 59 | @ResponseStatus(value = HttpStatus.OK) |
66 | 60 | public OAuth2ClientsParams saveOAuth2Params(@RequestBody OAuth2ClientsParams oauth2Params) throws ThingsboardException { |
67 | 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 | 64 | } catch (Exception e) { |
113 | - logEntityAction(emptyId(EntityType.OAUTH2_CLIENT_REGISTRATION), | |
114 | - null, | |
115 | - null, | |
116 | - ActionType.DELETED, e, domain); | |
117 | - | |
118 | 65 | throw handleException(e); |
119 | 66 | } |
120 | 67 | } | ... | ... |
... | ... | @@ -22,7 +22,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; |
22 | 22 | import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; |
23 | 23 | import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; |
24 | 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 | 26 | import org.thingsboard.server.dao.oauth2.OAuth2Service; |
27 | 27 | import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository; |
28 | 28 | import org.thingsboard.server.service.security.model.SecurityUser; |
... | ... | @@ -68,7 +68,7 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS |
68 | 68 | try { |
69 | 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 | 72 | OAuth2AuthorizedClient oAuth2AuthorizedClient = oAuth2AuthorizedClientService.loadAuthorizedClient( |
73 | 73 | token.getAuthorizedClientRegistrationId(), |
74 | 74 | token.getPrincipal().getName()); | ... | ... |
... | ... | @@ -32,7 +32,7 @@ public enum Resource { |
32 | 32 | USER(EntityType.USER), |
33 | 33 | WIDGETS_BUNDLE(EntityType.WIDGETS_BUNDLE), |
34 | 34 | WIDGET_TYPE(EntityType.WIDGET_TYPE), |
35 | - OAUTH2_CONFIGURATION(EntityType.OAUTH2_CLIENT_REGISTRATION), | |
35 | + OAUTH2_CONFIGURATION_INFO(EntityType.OAUTH2_CLIENT_REGISTRATION_INFO), | |
36 | 36 | OAUTH2_CONFIGURATION_TEMPLATE(EntityType.OAUTH2_CLIENT_REGISTRATION_TEMPLATE), |
37 | 37 | ; |
38 | 38 | ... | ... |
... | ... | @@ -35,7 +35,7 @@ public class SysAdminPermissions extends AbstractPermissions { |
35 | 35 | put(Resource.USER, userPermissionChecker); |
36 | 36 | put(Resource.WIDGETS_BUNDLE, systemEntityPermissionChecker); |
37 | 37 | put(Resource.WIDGET_TYPE, systemEntityPermissionChecker); |
38 | - put(Resource.OAUTH2_CONFIGURATION, PermissionChecker.allowAllPermissionChecker); | |
38 | + put(Resource.OAUTH2_CONFIGURATION_INFO, PermissionChecker.allowAllPermissionChecker); | |
39 | 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 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.oauth2; |
17 | 17 | |
18 | -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId; | |
19 | 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 | 20 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams; |
22 | 21 | |
23 | 22 | import java.util.List; |
24 | 23 | import java.util.UUID; |
25 | 24 | |
26 | 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 | 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 | 19 | * @author Andrew Shvayka |
20 | 20 | */ |
21 | 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 | 62 | return new WidgetsBundleId(uuid); |
63 | 63 | case WIDGET_TYPE: |
64 | 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 | 67 | case OAUTH2_CLIENT_REGISTRATION_TEMPLATE: |
68 | 68 | return new OAuth2ClientRegistrationTemplateId(uuid); |
69 | 69 | } | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/id/OAuth2ClientRegistrationInfoId.java
0 → 100644
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 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.oauth2; |
17 | 17 | |
18 | -import com.fasterxml.jackson.annotation.JsonProperty; | |
19 | 18 | import com.fasterxml.jackson.databind.JsonNode; |
20 | 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 | 22 | import java.util.List; |
25 | 23 | |
... | ... | @@ -30,8 +28,6 @@ import java.util.List; |
30 | 28 | @AllArgsConstructor |
31 | 29 | @Builder |
32 | 30 | public class ClientRegistrationDto { |
33 | - private OAuth2ClientRegistrationId id; | |
34 | - private long createdTime; | |
35 | 31 | private OAuth2MapperConfig mapperConfig; |
36 | 32 | private String clientId; |
37 | 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 | 17 | |
18 | 18 | import lombok.*; |
19 | 19 | |
20 | +@EqualsAndHashCode | |
20 | 21 | @Data |
21 | 22 | @ToString |
22 | -@Builder(toBuilder = true) | |
23 | 23 | @NoArgsConstructor |
24 | 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 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.oauth2; |
17 | 17 | |
18 | -import com.fasterxml.jackson.annotation.JsonProperty; | |
19 | 18 | import lombok.Data; |
20 | 19 | import lombok.EqualsAndHashCode; |
21 | 20 | import lombok.NoArgsConstructor; |
22 | 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 | 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 | 26 | @EqualsAndHashCode(callSuper = true) |
32 | 27 | @Data |
33 | -@ToString(exclude = {"clientSecret"}) | |
28 | +@ToString | |
34 | 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 | 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 | 36 | public OAuth2ClientRegistration(OAuth2ClientRegistration clientRegistration) { |
54 | 37 | super(clientRegistration); |
55 | - this.enabled = clientRegistration.enabled; | |
38 | + this.clientRegistrationId = clientRegistration.clientRegistrationId; | |
56 | 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 | 18 | import lombok.*; |
19 | 19 | |
20 | 20 | import java.util.List; |
21 | +import java.util.Set; | |
21 | 22 | |
22 | 23 | @EqualsAndHashCode |
23 | 24 | @Data |
... | ... | @@ -26,7 +27,6 @@ import java.util.List; |
26 | 27 | @NoArgsConstructor |
27 | 28 | @AllArgsConstructor |
28 | 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 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -16,11 +16,7 @@ |
16 | 16 | package org.thingsboard.server.common.data.oauth2; |
17 | 17 | |
18 | 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 | 21 | @EqualsAndHashCode |
26 | 22 | @Data |
... | ... | @@ -30,5 +26,5 @@ import java.util.Objects; |
30 | 26 | @AllArgsConstructor |
31 | 27 | public class OAuth2ClientsParams { |
32 | 28 | private boolean enabled; |
33 | - private List<OAuth2ClientsDomainParams> oAuth2DomainDtos; | |
29 | + private Set<OAuth2ClientsDomainParams> oAuth2DomainDtos; | |
34 | 30 | } |
\ No newline at end of file | ... | ... |
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 | 358 | * OAuth2 client registration constants. |
359 | 359 | */ |
360 | 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 | 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 | 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 | 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 | 368 | public static final String OAUTH2_DOMAIN_NAME_PROPERTY = "domain_name"; |
369 | + public static final String OAUTH2_DOMAIN_SCHEME_PROPERTY = "domain_scheme"; | |
366 | 370 | public static final String OAUTH2_CLIENT_ID_PROPERTY = "client_id"; |
367 | 371 | public static final String OAUTH2_CLIENT_SECRET_PROPERTY = "client_secret"; |
368 | 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 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | |
18 | -import com.fasterxml.jackson.databind.JsonNode; | |
19 | 18 | import lombok.Data; |
20 | 19 | import lombok.EqualsAndHashCode; |
21 | -import org.hibernate.annotations.Type; | |
22 | 20 | import org.hibernate.annotations.TypeDef; |
23 | 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 | 23 | import org.thingsboard.server.common.data.oauth2.*; |
26 | 24 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
27 | 25 | import org.thingsboard.server.dao.model.ModelConstants; |
... | ... | @@ -38,70 +36,15 @@ import java.util.UUID; |
38 | 36 | @Table(name = ModelConstants.OAUTH2_CLIENT_REGISTRATION_COLUMN_FAMILY_NAME) |
39 | 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 | 42 | @Column(name = ModelConstants.OAUTH2_DOMAIN_NAME_PROPERTY) |
44 | 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 | 49 | public OAuth2ClientRegistrationEntity() { |
107 | 50 | super(); |
... | ... | @@ -111,99 +54,22 @@ public class OAuth2ClientRegistrationEntity extends BaseSqlEntity<OAuth2ClientRe |
111 | 54 | if (clientRegistration.getId() != null) { |
112 | 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 | 65 | @Override |
157 | 66 | public OAuth2ClientRegistration toData() { |
158 | 67 | OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration(); |
159 | 68 | clientRegistration.setId(new OAuth2ClientRegistrationId(id)); |
160 | - clientRegistration.setEnabled(enabled); | |
69 | + clientRegistration.setClientRegistrationId(new OAuth2ClientRegistrationInfoId(clientRegistrationInfoId)); | |
161 | 70 | clientRegistration.setCreatedTime(createdTime); |
162 | 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 | 73 | return clientRegistration; |
208 | 74 | } |
209 | 75 | } | ... | ... |
dao/src/main/java/org/thingsboard/server/dao/model/sql/OAuth2ClientRegistrationInfoEntity.java
0 → 100644
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 | 21 | import org.springframework.security.oauth2.core.AuthorizationGrantType; |
22 | 22 | import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
23 | 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 | 26 | import java.util.UUID; |
28 | 27 | |
... | ... | @@ -34,12 +33,12 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep |
34 | 33 | |
35 | 34 | @Override |
36 | 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 | 42 | String registrationId = localClientRegistration.getUuidId().toString(); |
44 | 43 | return ClientRegistration.withRegistrationId(registrationId) |
45 | 44 | .clientName(localClientRegistration.getName()) |
... | ... | @@ -47,7 +46,6 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep |
47 | 46 | .authorizationUri(localClientRegistration.getAuthorizationUri()) |
48 | 47 | .clientSecret(localClientRegistration.getClientSecret()) |
49 | 48 | .tokenUri(localClientRegistration.getAccessTokenUri()) |
50 | - .redirectUriTemplate(localClientRegistration.getRedirectUriTemplate()) | |
51 | 49 | .scope(localClientRegistration.getScope()) |
52 | 50 | .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
53 | 51 | .userInfoUri(localClientRegistration.getUserInfoUri()) | ... | ... |
... | ... | @@ -18,13 +18,6 @@ package org.thingsboard.server.dao.oauth2; |
18 | 18 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; |
19 | 19 | import org.thingsboard.server.dao.Dao; |
20 | 20 | |
21 | -import java.util.List; | |
22 | -import java.util.UUID; | |
23 | - | |
24 | 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 | 19 | import org.springframework.beans.factory.annotation.Autowired; |
20 | 20 | import org.springframework.stereotype.Service; |
21 | 21 | import org.springframework.util.StringUtils; |
22 | -import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationId; | |
23 | 22 | import org.thingsboard.server.common.data.id.TenantId; |
24 | 23 | import org.thingsboard.server.common.data.oauth2.*; |
25 | 24 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
26 | 25 | import org.thingsboard.server.dao.exception.DataValidationException; |
26 | +import org.thingsboard.server.dao.exception.IncorrectParameterException; | |
27 | 27 | |
28 | 28 | import javax.transaction.Transactional; |
29 | 29 | import java.util.*; |
... | ... | @@ -39,78 +39,89 @@ public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Se |
39 | 39 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
40 | 40 | public static final String INCORRECT_CLIENT_REGISTRATION_ID = "Incorrect clientRegistrationId "; |
41 | 41 | public static final String INCORRECT_DOMAIN_NAME = "Incorrect domainName "; |
42 | + public static final String INCORRECT_DOMAIN_SCHEME = "Incorrect domainScheme "; | |
42 | 43 | |
43 | 44 | @Autowired |
45 | + private OAuth2ClientRegistrationInfoDao clientRegistrationInfoDao; | |
46 | + @Autowired | |
44 | 47 | private OAuth2ClientRegistrationDao clientRegistrationDao; |
45 | 48 | |
46 | 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 | 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 | 64 | .map(OAuth2Utils::toClientInfo) |
53 | 65 | .collect(Collectors.toList()); |
54 | 66 | } |
55 | 67 | |
56 | 68 | @Override |
57 | 69 | @Transactional |
58 | - public OAuth2ClientsParams saveOAuth2Params(OAuth2ClientsParams oauth2Params) { | |
70 | + public void saveOAuth2Params(OAuth2ClientsParams oauth2Params) { | |
59 | 71 | log.trace("Executing saveOAuth2Params [{}]", oauth2Params); |
60 | 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 | 88 | @Override |
69 | 89 | public OAuth2ClientsParams findOAuth2Params() { |
70 | 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 | 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 | 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 | 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 | 108 | private final Consumer<OAuth2ClientsParams> clientParamsValidator = oauth2Params -> { |
103 | 109 | if (oauth2Params == null |
104 | - || oauth2Params.getOAuth2DomainDtos() == null | |
105 | - || oauth2Params.getOAuth2DomainDtos().isEmpty()) { | |
110 | + || oauth2Params.getOAuth2DomainDtos() == null) { | |
106 | 111 | throw new DataValidationException("Domain params should be specified!"); |
107 | 112 | } |
108 | 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 | 126 | if (domainParams.getClientRegistrations() == null || domainParams.getClientRegistrations().isEmpty()) { |
116 | 127 | throw new DataValidationException("Client registrations should be specified!"); | ... | ... |
... | ... | @@ -15,93 +15,88 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.oauth2; |
17 | 17 | |
18 | +import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationInfoId; | |
18 | 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 | 23 | public class OAuth2Utils { |
27 | 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 | 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 | 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 | 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 | 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 | 96 | OAuth2ClientRegistration clientRegistration = new OAuth2ClientRegistration(); |
87 | - clientRegistration.setId(clientRegistrationDto.getId()); | |
88 | - clientRegistration.setEnabled(enabled); | |
89 | - clientRegistration.setCreatedTime(clientRegistrationDto.getCreatedTime()); | |
97 | + clientRegistration.setClientRegistrationId(clientRegistrationInfoId); | |
90 | 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 | 100 | return clientRegistration; |
106 | 101 | } |
107 | 102 | } | ... | ... |
... | ... | @@ -16,18 +16,15 @@ |
16 | 16 | package org.thingsboard.server.dao.sql.oauth2; |
17 | 17 | |
18 | 18 | import lombok.RequiredArgsConstructor; |
19 | +import lombok.extern.slf4j.Slf4j; | |
19 | 20 | import org.springframework.data.repository.CrudRepository; |
20 | 21 | import org.springframework.stereotype.Component; |
21 | 22 | import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistration; |
22 | -import org.thingsboard.server.dao.DaoUtil; | |
23 | 23 | import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity; |
24 | 24 | import org.thingsboard.server.dao.oauth2.OAuth2ClientRegistrationDao; |
25 | 25 | import org.thingsboard.server.dao.sql.JpaAbstractDao; |
26 | 26 | |
27 | -import java.util.ArrayList; | |
28 | -import java.util.List; | |
29 | 27 | import java.util.UUID; |
30 | -import java.util.stream.Collectors; | |
31 | 28 | |
32 | 29 | @Component |
33 | 30 | @RequiredArgsConstructor |
... | ... | @@ -45,23 +42,7 @@ public class JpaOAuth2ClientRegistrationDao extends JpaAbstractDao<OAuth2ClientR |
45 | 42 | } |
46 | 43 | |
47 | 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 | } | ... | ... |
dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/JpaOAuth2ClientRegistrationInfoDao.java
0 → 100644
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 | +} | ... | ... |
dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/OAuth2ClientRegistrationInfoRepository.java
0 → 100644
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 | 18 | import org.springframework.data.repository.CrudRepository; |
19 | 19 | import org.thingsboard.server.dao.model.sql.OAuth2ClientRegistrationEntity; |
20 | 20 | |
21 | -import java.util.List; | |
22 | 21 | import java.util.UUID; |
23 | 22 | |
24 | 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 | 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 | 296 | enabled boolean, |
297 | 297 | created_time bigint NOT NULL, |
298 | 298 | additional_info varchar, |
299 | - domain_name varchar(255), | |
300 | 299 | client_id varchar(255), |
301 | 300 | client_secret varchar(255), |
302 | 301 | authorization_uri varchar(255), |
303 | 302 | token_uri varchar(255), |
304 | - redirect_uri_template varchar(255), | |
305 | 303 | scope varchar(255), |
306 | 304 | user_info_uri varchar(255), |
307 | 305 | user_name_attribute_name varchar(255), |
... | ... | @@ -326,6 +324,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( |
326 | 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 | 335 | CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( |
330 | 336 | id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY, |
331 | 337 | created_time bigint NOT NULL, | ... | ... |
... | ... | @@ -316,17 +316,15 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary |
316 | 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 | 321 | enabled boolean, |
322 | 322 | created_time bigint NOT NULL, |
323 | 323 | additional_info varchar, |
324 | - domain_name varchar(255), | |
325 | 324 | client_id varchar(255), |
326 | 325 | client_secret varchar(255), |
327 | 326 | authorization_uri varchar(255), |
328 | 327 | token_uri varchar(255), |
329 | - redirect_uri_template varchar(255), | |
330 | 328 | scope varchar(255), |
331 | 329 | user_info_uri varchar(255), |
332 | 330 | user_name_attribute_name varchar(255), |
... | ... | @@ -351,6 +349,14 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration ( |
351 | 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 | 360 | CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( |
355 | 361 | id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY, |
356 | 362 | created_time bigint NOT NULL, | ... | ... |
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | +import com.google.common.collect.Sets; | |
18 | 19 | import org.junit.After; |
19 | 20 | import org.junit.Assert; |
20 | 21 | import org.junit.Before; |
... | ... | @@ -22,170 +23,413 @@ import org.junit.Test; |
22 | 23 | import org.springframework.beans.factory.annotation.Autowired; |
23 | 24 | import org.thingsboard.server.common.data.oauth2.*; |
24 | 25 | import org.thingsboard.server.dao.oauth2.OAuth2Service; |
25 | -import org.thingsboard.server.dao.oauth2.OAuth2Utils; | |
26 | 26 | |
27 | 27 | import java.util.*; |
28 | 28 | import java.util.stream.Collectors; |
29 | 29 | |
30 | -import static org.thingsboard.server.dao.oauth2.OAuth2Utils.toClientRegistrations; | |
31 | - | |
32 | 30 | public class BaseOAuth2ServiceTest extends AbstractServiceTest { |
31 | + private static final OAuth2ClientsParams EMPTY_PARAMS = new OAuth2ClientsParams(false, new HashSet<>()); | |
33 | 32 | |
34 | 33 | @Autowired |
35 | 34 | protected OAuth2Service oAuth2Service; |
36 | 35 | |
37 | 36 | @Before |
38 | 37 | public void beforeRun() { |
39 | - Assert.assertTrue(oAuth2Service.findAllClientRegistrations().isEmpty()); | |
38 | + Assert.assertTrue(oAuth2Service.findAllClientRegistrationInfos().isEmpty()); | |
40 | 39 | } |
41 | 40 | |
42 | 41 | @After |
43 | 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 | 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 | 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 | 119 | @Test |
86 | 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 | 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 | 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 | 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 | 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 | } | ... | ... |