92 changed files with 3414 additions and 1916 deletions
@ -0,0 +1,83 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
-- OAUTH2 UPDATE START |
|||
|
|||
ALTER TABLE IF EXISTS oauth2_mobile RENAME TO mobile_app; |
|||
ALTER TABLE IF EXISTS oauth2_domain RENAME TO domain; |
|||
|
|||
ALTER TABLE domain ADD COLUMN IF NOT EXISTS oauth2_enabled boolean, |
|||
ADD COLUMN IF NOT EXISTS propagate_to_edge boolean, |
|||
ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080', |
|||
DROP COLUMN IF EXISTS domain_scheme; |
|||
ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS oauth2_enabled boolean, |
|||
ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080'; |
|||
ALTER TABLE oauth2_registration ADD COLUMN IF NOT EXISTS tenant_id uuid DEFAULT '13814000-1dd2-11b2-8080-808080808080'; |
|||
ALTER TABLE oauth2_registration ADD COLUMN IF NOT EXISTS title varchar(100); |
|||
|
|||
CREATE TABLE IF NOT EXISTS domain_oauth2_registration ( |
|||
domain_id uuid NOT NULL, |
|||
oauth2_registration_id uuid NOT NULL, |
|||
CONSTRAINT fk_domain FOREIGN KEY (domain_id) REFERENCES domain(id) ON DELETE CASCADE, |
|||
CONSTRAINT fk_oauth2_registration FOREIGN KEY (oauth2_registration_id) REFERENCES oauth2_registration(id) ON DELETE CASCADE |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS mobile_app_oauth2_registration ( |
|||
mobile_app_id uuid NOT NULL, |
|||
oauth2_registration_id uuid NOT NULL, |
|||
CONSTRAINT fk_domain FOREIGN KEY (mobile_app_id) REFERENCES mobile_app(id) ON DELETE CASCADE, |
|||
CONSTRAINT fk_oauth2_registration FOREIGN KEY (oauth2_registration_id) REFERENCES oauth2_registration(id) ON DELETE CASCADE |
|||
); |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'oauth2_params') THEN |
|||
-- delete duplicated domains |
|||
DELETE FROM domain d1 USING domain d2 WHERE d1.created_time < d2.created_time AND d1.domain_name = d2.domain_name; |
|||
|
|||
UPDATE domain SET oauth2_enabled = p.enabled, |
|||
propagate_to_edge = p.edge_enabled |
|||
FROM oauth2_params p WHERE p.id = domain.oauth2_params_id; |
|||
|
|||
UPDATE mobile_app SET oauth2_enabled = p.enabled |
|||
FROM oauth2_params p WHERE p.id = mobile_app.oauth2_params_id; |
|||
|
|||
INSERT INTO domain_oauth2_registration(domain_id, oauth2_registration_id) |
|||
(SELECT d.id, r.id FROM domain d LEFT JOIN oauth2_registration r on d.oauth2_params_id = r.oauth2_params_id |
|||
WHERE r.platforms IS NULL OR r.platforms IN ('','WEB')); |
|||
|
|||
INSERT INTO mobile_app_oauth2_registration(mobile_app_id, oauth2_registration_id) |
|||
(SELECT m.id, r.id FROM mobile_app m LEFT JOIN oauth2_registration r on m.oauth2_params_id = r.oauth2_params_id |
|||
WHERE r.platforms IS NULL OR r.platforms IN ('','ANDROID','IOS')); |
|||
|
|||
ALTER TABLE mobile_app RENAME CONSTRAINT oauth2_mobile_pkey TO mobile_app_pkey; |
|||
ALTER TABLE domain RENAME CONSTRAINT oauth2_domain_pkey TO domain_pkey; |
|||
UPDATE oauth2_registration SET title = additional_info::jsonb->>'providerName' WHERE additional_info IS NOT NULL; |
|||
|
|||
ALTER TABLE domain DROP COLUMN oauth2_params_id; |
|||
ALTER TABLE mobile_app DROP COLUMN oauth2_params_id; |
|||
ALTER TABLE oauth2_registration DROP COLUMN oauth2_params_id; |
|||
|
|||
ALTER TABLE mobile_app ADD CONSTRAINT mobile_app_unq_key UNIQUE (pkg_name); |
|||
ALTER TABLE domain ADD CONSTRAINT domain_unq_key UNIQUE (domain_name); |
|||
|
|||
DROP TABLE IF EXISTS oauth2_params; |
|||
END IF; |
|||
END |
|||
$$; |
|||
|
|||
-- OAUTH2 UPDATE END |
|||
@ -0,0 +1,142 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.controller; |
|||
|
|||
import io.swagger.v3.oas.annotations.Parameter; |
|||
import io.swagger.v3.oas.annotations.media.ArraySchema; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.DeleteMapping; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.PathVariable; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.domain.DomainInfo; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.config.annotations.ApiOperation; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
import org.thingsboard.server.service.entitiy.domain.TbDomainService; |
|||
import org.thingsboard.server.service.security.permission.Operation; |
|||
import org.thingsboard.server.service.security.permission.Resource; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.common.data.audit.ActionType.UPDATED_OAUTH2_CLIENTS; |
|||
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; |
|||
import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; |
|||
import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; |
|||
|
|||
@RestController |
|||
@TbCoreComponent |
|||
@RequestMapping("/api") |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class DomainController extends BaseController { |
|||
|
|||
private final TbDomainService tbDomainService; |
|||
|
|||
@ApiOperation(value = "Save or Update Domain (saveDomain)", |
|||
notes = "Create or update the Domain. When creating domain, platform generates Domain Id as " + UUID_WIKI_LINK + |
|||
"The newly created Domain Id will be present in the response. " + |
|||
"Specify existing Domain Id to update the domain. " + |
|||
"Referencing non-existing Domain Id will cause 'Not Found' error." + |
|||
"\n\nDomain name is unique for entire platform setup.\n\n") |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@PostMapping(value = "/domain") |
|||
public Domain saveDomain( |
|||
@Parameter(description = "A JSON value representing the Domain.", required = true) |
|||
@RequestBody Domain domain, |
|||
@Parameter(description = "A list of oauth2 client registration ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string"))) |
|||
@RequestParam(name = "oauth2ClientRegistrationIds", required = false) String[] ids) throws Exception { |
|||
List<String> oauth2ClientIds = ids != null ? Arrays.asList(ids) : Collections.emptyList(); |
|||
domain.setTenantId(getCurrentUser().getTenantId()); |
|||
checkEntity(domain.getId(), domain, Resource.DOMAIN); |
|||
List<OAuth2RegistrationId> oAuth2ClientIds = new ArrayList<>(); |
|||
for (String id : oauth2ClientIds) { |
|||
OAuth2RegistrationId oauth2ClientId = new OAuth2RegistrationId(toUUID(id)); |
|||
checkOauth2ClientId(oauth2ClientId, Operation.READ); |
|||
oAuth2ClientIds.add(oauth2ClientId); |
|||
} |
|||
return tbDomainService.save(domain, oAuth2ClientIds, getCurrentUser()); |
|||
} |
|||
|
|||
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)", |
|||
notes = "Update oauth2 clients for the specified domain. ") |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@PostMapping(value = "/domain/{id}/oauth2Clients") |
|||
public void updateOauth2Clients(@PathVariable UUID id, |
|||
@RequestBody UUID[] oauth2ClientIds) throws ThingsboardException { |
|||
DomainId domainId = new DomainId(id); |
|||
Domain domain = null; |
|||
try { |
|||
domain = checkDomainId(domainId, Operation.WRITE); |
|||
List<OAuth2RegistrationId> oAuth2ClientIds = new ArrayList<>(); |
|||
for (UUID outh2CLientId : oauth2ClientIds) { |
|||
OAuth2RegistrationId oAuth2RegistrationId = new OAuth2RegistrationId(outh2CLientId); |
|||
checkEntityId(oAuth2RegistrationId, Operation.READ); |
|||
oAuth2ClientIds.add(oAuth2RegistrationId); |
|||
} |
|||
domainService.updateOauth2Clients(getTenantId(), domainId, oAuth2ClientIds); |
|||
logEntityActionService.logEntityAction(domain.getTenantId(), domain.getId(), domain, |
|||
UPDATED_OAUTH2_CLIENTS, getCurrentUser(), oAuth2ClientIds.toString()); |
|||
} catch (Exception e) { |
|||
if (domain != null) { |
|||
logEntityActionService.logEntityAction(getTenantId(), domainId, domain, |
|||
ActionType.UPDATED_OAUTH2_CLIENTS, getCurrentUser(), e); |
|||
} |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
@ApiOperation(value = "Get Domain infos (getDomainInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@GetMapping(value = "/domain/infos") |
|||
public List<DomainInfo> getDomainInfos() throws ThingsboardException { |
|||
return domainService.findDomainInfosByTenantId(getTenantId()); |
|||
} |
|||
|
|||
@ApiOperation(value = "Get Domain info by Id (getDomainInfoById)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@GetMapping(value = "/domain/info/{id}") |
|||
public DomainInfo getDomainInfoById(@PathVariable UUID id) throws ThingsboardException { |
|||
DomainId domainId = new DomainId(id); |
|||
return checkEntityId(domainId, domainService::findDomainInfoById, Operation.READ); |
|||
} |
|||
|
|||
@ApiOperation(value = "Delete Domain by ID (deleteDomain)", |
|||
notes = "Deletes Domain by ID. Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAuthority('SYS_ADMIN')") |
|||
@DeleteMapping(value = "/domain/{id}") |
|||
public void deleteDomain(@PathVariable UUID id) throws Exception { |
|||
DomainId domainId = new DomainId(id); |
|||
checkDomainId(domainId, Operation.DELETE); |
|||
domainService.deleteDomainById(getTenantId(), domainId); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,142 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.controller; |
|||
|
|||
import io.swagger.v3.oas.annotations.Parameter; |
|||
import io.swagger.v3.oas.annotations.media.ArraySchema; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.DeleteMapping; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.PathVariable; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppInfo; |
|||
import org.thingsboard.server.config.annotations.ApiOperation; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
import org.thingsboard.server.service.entitiy.mobile.TbMobileAppService; |
|||
import org.thingsboard.server.service.security.permission.Operation; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.common.data.audit.ActionType.UPDATED_OAUTH2_CLIENTS; |
|||
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; |
|||
import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; |
|||
import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; |
|||
|
|||
@RestController |
|||
@TbCoreComponent |
|||
@RequestMapping("/api") |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class MobileAppController extends BaseController { |
|||
|
|||
private final TbMobileAppService tbMobileAppService; |
|||
|
|||
@ApiOperation(value = "Save Or update Mobile app (saveMobileApp)", |
|||
notes = "Create or update the Mobile app. When creating mobile app, platform generates Mobile App Id as " + UUID_WIKI_LINK + |
|||
"The newly created Mobile App Id will be present in the response. " + |
|||
"Specify existing Mobile App Id to update the domain. " + |
|||
"Referencing non-existing Mobile App Id will cause 'Not Found' error." + |
|||
"\n\nMobile app package name is unique for entire platform setup.\n\n") |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@PostMapping(value = "/mobileApp") |
|||
public MobileApp saveMobileApp( |
|||
@Parameter(description = "A JSON value representing the Domain.", required = true) |
|||
@RequestBody MobileApp mobileApp, |
|||
@Parameter(description = "A list of entity group ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string"))) |
|||
@RequestParam(name = "oauth2RegistrationIds", required = false) UUID[] oauth2RegistrationIds) throws Exception { |
|||
mobileApp.setTenantId(getCurrentUser().getTenantId()); |
|||
|
|||
List<OAuth2RegistrationId> oAuth2Registrations = new ArrayList<>(); |
|||
for (UUID id : oauth2RegistrationIds) { |
|||
OAuth2RegistrationId oauth2ClientId = new OAuth2RegistrationId(id); |
|||
checkOauth2ClientId(oauth2ClientId, Operation.READ); |
|||
oAuth2Registrations.add(oauth2ClientId); |
|||
} |
|||
return tbMobileAppService.save(mobileApp, oAuth2Registrations, getCurrentUser()); |
|||
} |
|||
|
|||
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)", |
|||
notes = "Update oauth2 clients to the specified mobile app. ") |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@PostMapping(value = "/mobileApp/{id}/updateOauth2Clients") |
|||
public void updateOauth2Clients(@PathVariable UUID id, |
|||
@RequestBody UUID[] oauth2ClientIds) throws ThingsboardException { |
|||
MobileAppId mobileAppId = new MobileAppId(id); |
|||
MobileApp mobileApp = null; |
|||
try { |
|||
mobileApp = checkMobileAppId(mobileAppId, Operation.WRITE); |
|||
List<OAuth2RegistrationId> oAuth2ClientIds = new ArrayList<>(); |
|||
for (UUID outh2CLientId : oauth2ClientIds) { |
|||
OAuth2RegistrationId oAuth2RegistrationId = new OAuth2RegistrationId(outh2CLientId); |
|||
checkEntityId(oAuth2RegistrationId, Operation.READ); |
|||
oAuth2ClientIds.add(oAuth2RegistrationId); |
|||
} |
|||
mobileAppService.updateOauth2Clients(getTenantId(), mobileAppId, oAuth2ClientIds); |
|||
logEntityActionService.logEntityAction(getTenantId(), mobileAppId, mobileApp, |
|||
UPDATED_OAUTH2_CLIENTS, getCurrentUser(), oAuth2ClientIds.toString()); |
|||
} catch (Exception e) { |
|||
if (mobileApp != null) { |
|||
logEntityActionService.logEntityAction(getTenantId(), mobileAppId, mobileApp, |
|||
ActionType.UPDATED_OAUTH2_CLIENTS, getCurrentUser(), e); |
|||
} |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
@ApiOperation(value = "Get mobile app infos (getMobileAppInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@GetMapping(value = "/mobileApp/infos") |
|||
public List<MobileAppInfo> getMobileAppInfos() throws ThingsboardException { |
|||
TenantId tenantId = getCurrentUser().getTenantId(); |
|||
return mobileAppService.findMobileAppInfosByTenantId(tenantId); |
|||
} |
|||
|
|||
@ApiOperation(value = "Get mobile info by id (getMobileAppInfoById)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
|||
@GetMapping(value = "/mobileApp/info/{id}") |
|||
public MobileAppInfo getMobileAppInfoById(@PathVariable UUID id) throws ThingsboardException { |
|||
MobileAppId mobileAppId = new MobileAppId(id); |
|||
return checkEntityId(mobileAppId, mobileAppService::findMobileAppInfoById, Operation.READ); |
|||
} |
|||
|
|||
@ApiOperation(value = "Delete Mobile App by ID (deleteMobileApp)", |
|||
notes = "Deletes Mobile App by ID. Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) |
|||
@PreAuthorize("hasAuthority('SYS_ADMIN')") |
|||
@DeleteMapping(value = "/mobileApp/{id}") |
|||
public void deleteMobileApp(@PathVariable UUID id) throws Exception { |
|||
MobileAppId mobileAppId = new MobileAppId(id); |
|||
checkMobileAppId(mobileAppId, Operation.DELETE); |
|||
mobileAppService.deleteMobileAppById(getTenantId(), mobileAppId); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.entitiy.domain; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.util.CollectionUtils; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.domain.DomainService; |
|||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
|||
|
|||
import java.util.List; |
|||
|
|||
import static org.thingsboard.server.common.data.audit.ActionType.UPDATED_OAUTH2_CLIENTS; |
|||
|
|||
@Service |
|||
@AllArgsConstructor |
|||
public class DefaultTbDomainService extends AbstractTbEntityService implements TbDomainService { |
|||
|
|||
private final DomainService domainService; |
|||
|
|||
@Override |
|||
public Domain save(Domain domain, List<OAuth2RegistrationId> oAuth2Clients, User user) throws Exception { |
|||
ActionType actionType = domain.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
|||
TenantId tenantId = domain.getTenantId(); |
|||
try { |
|||
Domain savedDomain = checkNotNull(domainService.saveDomain(tenantId, domain)); |
|||
logEntityActionService.logEntityAction(tenantId, savedDomain.getId(), domain, actionType, user); |
|||
if (!CollectionUtils.isEmpty(oAuth2Clients)) { |
|||
domainService.updateOauth2Clients(domain.getTenantId(), savedDomain.getId(), oAuth2Clients); |
|||
logEntityActionService.logEntityAction(domain.getTenantId(), savedDomain.getId(), savedDomain, |
|||
UPDATED_OAUTH2_CLIENTS, user, oAuth2Clients.toString()); |
|||
} |
|||
return savedDomain; |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), domain, actionType, user, e); |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void delete(Domain domain, User user) { |
|||
ActionType actionType = ActionType.DELETED; |
|||
TenantId tenantId = domain.getTenantId(); |
|||
DomainId domainId = domain.getId(); |
|||
try { |
|||
domainService.deleteDomainById(tenantId, domainId); |
|||
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, domain.getName()); |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), actionType, user, e, |
|||
domainId.toString()); |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.entitiy.mobile; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.util.CollectionUtils; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.dao.mobile.MobileAppService; |
|||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Service |
|||
@AllArgsConstructor |
|||
public class DefaultTbMobileAppService extends AbstractTbEntityService implements TbMobileAppService { |
|||
|
|||
private final MobileAppService mobileAppService; |
|||
|
|||
@Override |
|||
public MobileApp save(MobileApp mobileApp, List<OAuth2RegistrationId> oauth2Clients, User user) throws Exception { |
|||
ActionType actionType = mobileApp.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
|||
TenantId tenantId = mobileApp.getTenantId(); |
|||
try { |
|||
MobileApp savedMobileApp = checkNotNull(mobileAppService.saveMobileApp(tenantId, mobileApp)); |
|||
logEntityActionService.logEntityAction(tenantId, savedMobileApp.getId(), mobileApp, actionType, user); |
|||
if (!CollectionUtils.isEmpty(oauth2Clients)) { |
|||
mobileAppService.updateOauth2Clients(tenantId, savedMobileApp.getId(), oauth2Clients); |
|||
logEntityActionService.logEntityAction(tenantId, savedMobileApp.getId(), savedMobileApp, |
|||
ActionType.UPDATED_OAUTH2_CLIENTS, user, oauth2Clients.toString()); |
|||
} |
|||
return savedMobileApp; |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.MOBILE_APP), mobileApp, actionType, user, e); |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void delete(MobileApp mobileApp, User user) { |
|||
ActionType actionType = ActionType.DELETED; |
|||
TenantId tenantId = mobileApp.getTenantId(); |
|||
MobileAppId mobileAppId = mobileApp.getId(); |
|||
try { |
|||
mobileAppService.deleteMobileAppById(tenantId, mobileAppId); |
|||
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, mobileApp.getPkgName()); |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.MOBILE_APP), actionType, user, e, |
|||
mobileAppId.toString()); |
|||
throw e; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.entitiy.oauth2client; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2ClientService; |
|||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
|||
|
|||
@Service |
|||
@AllArgsConstructor |
|||
public class DefaultTbOauth2ClientService extends AbstractTbEntityService implements TbOauth2ClientService { |
|||
|
|||
private final OAuth2ClientService oAuth2ClientService; |
|||
|
|||
@Override |
|||
public OAuth2Registration save(OAuth2Registration oAuth2Registration, User user) throws Exception { |
|||
ActionType actionType = oAuth2Registration.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
|||
TenantId tenantId = oAuth2Registration.getTenantId(); |
|||
try { |
|||
OAuth2Registration savedRegistration = checkNotNull(oAuth2ClientService.saveOAuth2Client(tenantId, oAuth2Registration)); |
|||
logEntityActionService.logEntityAction(tenantId, savedRegistration.getId(), oAuth2Registration, actionType, user); |
|||
return savedRegistration; |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OAUTH2_CLIENT), oAuth2Registration, actionType, user, e); |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void delete(OAuth2Registration oAuth2Registration, User user) { |
|||
ActionType actionType = ActionType.DELETED; |
|||
TenantId tenantId = oAuth2Registration.getTenantId(); |
|||
OAuth2RegistrationId oAuth2RegistrationId = oAuth2Registration.getId(); |
|||
try { |
|||
oAuth2ClientService.deleteById(tenantId, oAuth2RegistrationId); |
|||
logEntityActionService.logEntityAction(tenantId, oAuth2RegistrationId, oAuth2Registration, actionType, user, oAuth2Registration.getName()); |
|||
} catch (Exception e) { |
|||
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OAUTH2_CLIENT), actionType, user, e, |
|||
oAuth2RegistrationId.toString()); |
|||
throw e; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.entitiy.oauth2client; |
|||
|
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface TbOauth2ClientService { |
|||
|
|||
OAuth2Registration save(OAuth2Registration oAuth2Registration, User user) throws Exception; |
|||
|
|||
void delete(OAuth2Registration oAuth2Registration, User user); |
|||
|
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.domain; |
|||
|
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.domain.DomainInfo; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.entity.EntityDaoService; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface DomainService extends EntityDaoService { |
|||
|
|||
Domain saveDomain(TenantId tenantId, Domain domain); |
|||
|
|||
void deleteDomainById(TenantId tenantId, DomainId domainId); |
|||
|
|||
Domain findDomainById(TenantId tenantId, DomainId domainId); |
|||
|
|||
List<DomainInfo> findDomainInfosByTenantId(TenantId tenantId); |
|||
|
|||
DomainInfo findDomainInfoById(TenantId tenantId, DomainId domainId); |
|||
|
|||
boolean isOauth2Enabled(TenantId tenantId); |
|||
|
|||
void updateOauth2Clients(TenantId tenantId, DomainId domainId, List<OAuth2RegistrationId> oAuth2ClientIds); |
|||
|
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.mobile; |
|||
|
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppInfo; |
|||
import org.thingsboard.server.dao.entity.EntityDaoService; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface MobileAppService extends EntityDaoService { |
|||
|
|||
MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp); |
|||
|
|||
void deleteMobileAppById(TenantId tenantId, MobileAppId mobileAppId); |
|||
|
|||
MobileApp findMobileAppById(TenantId tenantId, MobileAppId mobileAppId); |
|||
|
|||
List<MobileAppInfo> findMobileAppInfosByTenantId(TenantId tenantId); |
|||
|
|||
MobileAppInfo findMobileAppInfoById(TenantId tenantId, MobileAppId mobileAppId); |
|||
|
|||
void updateOauth2Clients(TenantId tenantId, MobileAppId mobileAppId, List<OAuth2RegistrationId> oAuth2ClientIds); |
|||
|
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.domain; |
|||
|
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.HasName; |
|||
import org.thingsboard.server.common.data.HasTenantId; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class Domain extends BaseData<DomainId> implements HasTenantId, HasName { |
|||
|
|||
@Schema(description = "JSON object with Tenant Id") |
|||
private TenantId tenantId; |
|||
@Schema(description = "Domain name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private String name; |
|||
@Schema(description = "Whether OAuth2 settings are enabled or not") |
|||
private boolean oauth2Enabled; |
|||
@Schema(description = "Whether OAuth2 settings are enabled on Edge or not") |
|||
private boolean propagateToEdge; |
|||
|
|||
public Domain(Domain domain) { |
|||
super(domain); |
|||
this.tenantId = domain.tenantId; |
|||
this.name = domain.name; |
|||
this.oauth2Enabled = domain.oauth2Enabled; |
|||
this.propagateToEdge = domain.propagateToEdge; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.mobile; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.HasName; |
|||
import org.thingsboard.server.common.data.HasTenantId; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class MobileApp extends BaseData<MobileAppId> implements HasTenantId, HasName { |
|||
|
|||
@Schema(description = "JSON object with Tenant Id") |
|||
private TenantId tenantId; |
|||
@Schema(description = "Application package name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private String pkgName; |
|||
@Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private String appSecret; |
|||
@Schema(description = "Whether OAuth2 settings are enabled or not") |
|||
private boolean oauth2Enabled; |
|||
|
|||
public MobileApp(MobileApp mobile) { |
|||
super(mobile); |
|||
this.tenantId = mobile.tenantId; |
|||
this.pkgName = mobile.pkgName; |
|||
this.appSecret = mobile.appSecret; |
|||
this.oauth2Enabled = mobile.oauth2Enabled; |
|||
} |
|||
|
|||
@Override |
|||
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
|||
@Schema(description = "Mobile app package name", example = "my.mobile.app", accessMode = Schema.AccessMode.READ_ONLY) |
|||
public String getName() { |
|||
return pkgName; |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.mobile; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class MobileAppOauth2Registration { |
|||
|
|||
private MobileAppId mobileAppId; |
|||
private OAuth2RegistrationId oAuth2RegistrationId; |
|||
|
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.id.OAuth2DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class OAuth2Domain extends BaseData<OAuth2DomainId> { |
|||
|
|||
private OAuth2ParamsId oauth2ParamsId; |
|||
private String domainName; |
|||
private SchemeType domainScheme; |
|||
|
|||
public OAuth2Domain(OAuth2Domain domain) { |
|||
super(domain); |
|||
this.oauth2ParamsId = domain.oauth2ParamsId; |
|||
this.domainName = domain.domainName; |
|||
this.domainScheme = domain.domainScheme; |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Builder |
|||
@Schema |
|||
public class OAuth2DomainInfo { |
|||
@Schema(description = "Domain scheme. Mixed scheme means than both HTTP and HTTPS are going to be used", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private SchemeType scheme; |
|||
@Schema(description = "Domain name. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private String name; |
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.id.OAuth2MobileId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class OAuth2Mobile extends BaseData<OAuth2MobileId> { |
|||
|
|||
private OAuth2ParamsId oauth2ParamsId; |
|||
private String pkgName; |
|||
private String appSecret; |
|||
|
|||
public OAuth2Mobile(OAuth2Mobile mobile) { |
|||
super(mobile); |
|||
this.oauth2ParamsId = mobile.oauth2ParamsId; |
|||
this.pkgName = mobile.pkgName; |
|||
this.appSecret = mobile.appSecret; |
|||
} |
|||
} |
|||
@ -1,46 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
|
|||
import java.util.List; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@Builder(toBuilder = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Schema |
|||
public class OAuth2ParamsInfo { |
|||
|
|||
@Schema(description = "List of configured domains where OAuth2 platform will redirect a user after successful " + |
|||
"authentication. Cannot be empty. There have to be only one domain with specific name with scheme type 'MIXED'. " + |
|||
"Configured domains with the same name must have different scheme types", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private List<OAuth2DomainInfo> domainInfos; |
|||
@Schema(description = "Mobile applications settings. Application package name must be unique within the list", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private List<OAuth2MobileInfo> mobileInfos; |
|||
@Schema(description = "List of OAuth2 provider settings. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) |
|||
private List<OAuth2RegistrationInfo> clientRegistrations; |
|||
|
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.domain; |
|||
|
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.domain.DomainOauth2Registration; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface DomainDao extends Dao<Domain> { |
|||
|
|||
List<Domain> findByTenantId(TenantId tenantId); |
|||
|
|||
int countDomainByTenantIdAndOauth2Enabled(TenantId tenantId, boolean oauth2Enabled); |
|||
|
|||
List<DomainOauth2Registration> findOauth2ClientsByDomainId(TenantId tenantId, DomainId domainId); |
|||
|
|||
void saveOauth2Clients(DomainOauth2Registration domainOauth2Registration); |
|||
|
|||
void removeOauth2Clients(DomainId domainId, OAuth2RegistrationId oAuth2RegistrationId); |
|||
|
|||
} |
|||
@ -0,0 +1,167 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.domain; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.hibernate.exception.ConstraintViolationException; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.domain.DomainInfo; |
|||
import org.thingsboard.server.common.data.domain.DomainOauth2Registration; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.HasId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; |
|||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2RegistrationDao; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
import org.thingsboard.server.dao.service.Validator; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Comparator; |
|||
import java.util.List; |
|||
import java.util.Optional; |
|||
|
|||
import static org.thingsboard.server.dao.service.Validator.validateIds; |
|||
|
|||
@Slf4j |
|||
@Service |
|||
public class DomainServiceImpl extends AbstractEntityService implements DomainService { |
|||
|
|||
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|||
public static final String INCORRECT_DOMAIN_ID = "Incorrect domainId "; |
|||
|
|||
@Autowired |
|||
private OAuth2RegistrationDao oauth2RegistrationDao; |
|||
@Autowired |
|||
private DomainDao domainDao; |
|||
@Autowired |
|||
private DataValidator<Domain> domainValidator; |
|||
|
|||
@Override |
|||
public Domain saveDomain(TenantId tenantId, Domain domain) { |
|||
log.trace("Executing saveDomain [{}]", domain); |
|||
domainValidator.validate(domain, Domain::getTenantId); |
|||
try { |
|||
Domain savedDomain = domainDao.save(tenantId, domain); |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedDomain).build()); |
|||
return savedDomain; |
|||
} catch (Exception t) { |
|||
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|||
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("domain_unq_key")) { |
|||
throw new DataValidationException("Domain with such name and scheme already exists!"); |
|||
} else { |
|||
throw t; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void updateOauth2Clients(TenantId tenantId, DomainId domainId, List<OAuth2RegistrationId> oAuth2ClientIds) { |
|||
log.trace("Executing addOauth2Clients, domainId [{}], oAuth2ClientIds [{}]", domainId, oAuth2ClientIds); |
|||
Validator.validateId(tenantId, id -> INCORRECT_TENANT_ID + id); |
|||
Validator.validateId(domainId, id -> INCORRECT_DOMAIN_ID + id); |
|||
Validator.checkNotNull(oAuth2ClientIds, "Incorrect oAuth2ClientIds " + oAuth2ClientIds); |
|||
if (!oAuth2ClientIds.isEmpty()) { |
|||
validateIds(oAuth2ClientIds, ids -> "Incorrect oAuth2ClientIds " + ids); |
|||
} |
|||
List<DomainOauth2Registration> oauth2Clients = new ArrayList<>(); |
|||
for (OAuth2RegistrationId oAuth2RegistrationId: oAuth2ClientIds) { |
|||
oauth2Clients.add(new DomainOauth2Registration(domainId, oAuth2RegistrationId)); |
|||
} |
|||
List<DomainOauth2Registration> existingClients = domainDao.findOauth2ClientsByDomainId(tenantId, domainId); |
|||
List<OAuth2RegistrationId> toRemove = existingClients.stream() |
|||
.map(DomainOauth2Registration::getOAuth2RegistrationId) |
|||
.filter(clientId -> oAuth2ClientIds.stream().noneMatch(oauth2ClientId -> |
|||
oauth2ClientId.equals(clientId))).toList(); |
|||
for (OAuth2RegistrationId clientId : toRemove) { |
|||
domainDao.removeOauth2Clients(domainId, clientId); |
|||
} |
|||
for (DomainOauth2Registration domainOauth2Registration : oauth2Clients) { |
|||
domainDao.saveOauth2Clients(domainOauth2Registration); |
|||
} |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId) |
|||
.entityId(domainId).created(false).build()); |
|||
} |
|||
|
|||
@Override |
|||
public void deleteDomainById(TenantId tenantId, DomainId domainId) { |
|||
log.trace("Executing deleteDomain [{}]", domainId.getId()); |
|||
domainDao.removeById(tenantId, domainId.getId()); |
|||
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(domainId).build()); |
|||
} |
|||
|
|||
@Override |
|||
public Domain findDomainById(TenantId tenantId, DomainId domainId) { |
|||
log.trace("Executing findDomainInfo [{}] [{}]", tenantId, domainId); |
|||
return domainDao.findById(tenantId, domainId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public List<DomainInfo> findDomainInfosByTenantId(TenantId tenantId) { |
|||
log.trace("Executing findDomainInfo [{}]", tenantId); |
|||
List<Domain> domains = domainDao.findByTenantId(tenantId); |
|||
List<DomainInfo> domainInfos = new ArrayList<>(); |
|||
domains.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(domain -> { |
|||
domainInfos.add(new DomainInfo(domain, oauth2RegistrationDao.findInfosByDomainId(domain.getUuidId()))); |
|||
}); |
|||
return domainInfos; |
|||
} |
|||
|
|||
@Override |
|||
public DomainInfo findDomainInfoById(TenantId tenantId, DomainId domainId) { |
|||
log.trace("Executing findDomainInfoById [{}] [{}]", tenantId, domainId); |
|||
Domain domain = domainDao.findById(tenantId, domainId.getId()); |
|||
if (domain == null) { |
|||
return null; |
|||
} |
|||
return new DomainInfo(domain, oauth2RegistrationDao.findInfosByDomainId(domain.getUuidId())); |
|||
} |
|||
|
|||
@Override |
|||
public boolean isOauth2Enabled(TenantId tenantId) { |
|||
log.trace("Executing isOauth2Enabled [{}] ", tenantId); |
|||
return domainDao.countDomainByTenantIdAndOauth2Enabled(tenantId, true) > 0; |
|||
} |
|||
|
|||
@Override |
|||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) { |
|||
return Optional.ofNullable(findDomainById(tenantId, new DomainId(entityId.getId()))); |
|||
} |
|||
|
|||
@Override |
|||
public EntityType getEntityType() { |
|||
return EntityType.DOMAIN; |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
|||
Domain domain = domainDao.findById(tenantId, id.getId()); |
|||
if (domain == null) { |
|||
return; |
|||
} |
|||
deleteDomainById(tenantId, domain.getId()); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.mobile; |
|||
|
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Registration; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface MobileAppDao extends Dao<MobileApp> { |
|||
|
|||
List<MobileApp> findByTenantId(TenantId tenantId); |
|||
|
|||
List<MobileAppOauth2Registration> findOauth2ClientsByMobileAppId(TenantId tenantId, MobileAppId mobileAppId); |
|||
|
|||
void saveOauth2Clients(MobileAppOauth2Registration mobileAppOauth2Registration); |
|||
|
|||
void removeOauth2Clients(MobileAppId mobileAppId, OAuth2RegistrationId oAuth2RegistrationId); |
|||
} |
|||
@ -0,0 +1,163 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.mobile; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.hibernate.exception.ConstraintViolationException; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.HasId; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppInfo; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; |
|||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2RegistrationDao; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
import org.thingsboard.server.dao.service.Validator; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Comparator; |
|||
import java.util.List; |
|||
import java.util.Optional; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import static org.thingsboard.server.dao.service.Validator.validateIds; |
|||
|
|||
@Slf4j |
|||
@Service |
|||
public class MobileAppServiceImpl extends AbstractEntityService implements MobileAppService { |
|||
|
|||
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|||
public static final String INCORRECT_MOBILE_APP_ID = "Incorrect mobileApppId "; |
|||
|
|||
@Autowired |
|||
private OAuth2RegistrationDao oauth2RegistrationDao; |
|||
@Autowired |
|||
private MobileAppDao mobileAppDao; |
|||
@Autowired |
|||
private DataValidator<MobileApp> mobileAppValidator; |
|||
|
|||
@Override |
|||
public MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp) { |
|||
log.trace("Executing saveMobileApp [{}]", mobileApp); |
|||
mobileAppValidator.validate(mobileApp, MobileApp::getTenantId); |
|||
try { |
|||
MobileApp savedMobileApp = mobileAppDao.save(tenantId, mobileApp); |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedMobileApp).build()); |
|||
return savedMobileApp; |
|||
} catch (Exception t) { |
|||
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|||
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("mobile_app_unq_key")) { |
|||
throw new DataValidationException("Mobile app with such package already exists!"); |
|||
} else { |
|||
throw t; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void deleteMobileAppById(TenantId tenantId, MobileAppId mobileAppId) { |
|||
log.trace("Executing deleteMobileAppById [{}]", mobileAppId.getId()); |
|||
mobileAppDao.removeById(tenantId, mobileAppId.getId()); |
|||
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(mobileAppId).build()); |
|||
} |
|||
|
|||
@Override |
|||
public MobileApp findMobileAppById(TenantId tenantId, MobileAppId mobileAppId) { |
|||
log.trace("Executing findMobileAppById [{}] [{}]", tenantId, mobileAppId); |
|||
return mobileAppDao.findById(tenantId, mobileAppId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public List<MobileAppInfo> findMobileAppInfosByTenantId(TenantId tenantId) { |
|||
log.trace("Executing findMobileAppInfosByTenantId [{}]", tenantId); |
|||
List<MobileApp> mobileApps = mobileAppDao.findByTenantId(tenantId); |
|||
List<MobileAppInfo> mobileAppInfos = new ArrayList<>(); |
|||
mobileApps.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(mobileApp -> { |
|||
mobileAppInfos.add(new MobileAppInfo(mobileApp, oauth2RegistrationDao.findInfosByMobileAppId(mobileApp.getUuidId()))); |
|||
}); |
|||
return mobileAppInfos; |
|||
} |
|||
|
|||
@Override |
|||
public MobileAppInfo findMobileAppInfoById(TenantId tenantId, MobileAppId mobileAppId) { |
|||
log.trace("Executing findMobileAppInfoById [{}] [{}]", tenantId, mobileAppId); |
|||
MobileApp mobileApp = mobileAppDao.findById(tenantId, mobileAppId.getId()); |
|||
if (mobileApp == null) { |
|||
return null; |
|||
} |
|||
return new MobileAppInfo(mobileApp, oauth2RegistrationDao.findInfosByMobileAppId(mobileApp.getUuidId())); |
|||
} |
|||
|
|||
@Override |
|||
public void updateOauth2Clients(TenantId tenantId, MobileAppId mobileAppId, List<OAuth2RegistrationId> oAuth2ClientIds) { |
|||
log.trace("Executing updateOauth2Clients, mobileAppId [{}], oAuth2ClientIds [{}]", mobileAppId, oAuth2ClientIds); |
|||
Validator.validateId(tenantId, id -> INCORRECT_TENANT_ID + id); |
|||
Validator.validateId(mobileAppId, id -> INCORRECT_MOBILE_APP_ID + id); |
|||
Validator.checkNotNull(oAuth2ClientIds, "Incorrect oAuth2ClientIds " + oAuth2ClientIds); |
|||
if (!oAuth2ClientIds.isEmpty()) { |
|||
validateIds(oAuth2ClientIds, ids -> "Incorrect oAuth2ClientIds " + ids); |
|||
} |
|||
List<MobileAppOauth2Registration> oauth2Clients = new ArrayList<>(); |
|||
for (OAuth2RegistrationId oAuth2RegistrationId: oAuth2ClientIds) { |
|||
oauth2Clients.add(new MobileAppOauth2Registration(mobileAppId, oAuth2RegistrationId)); |
|||
} |
|||
List<MobileAppOauth2Registration> existingClients = mobileAppDao.findOauth2ClientsByMobileAppId(tenantId, mobileAppId); |
|||
List<OAuth2RegistrationId> toRemove = existingClients.stream() |
|||
.map(MobileAppOauth2Registration::getOAuth2RegistrationId) |
|||
.filter(clientId -> oAuth2ClientIds.stream().noneMatch(oauth2ClientId -> |
|||
oauth2ClientId.equals(clientId))).toList(); |
|||
for (OAuth2RegistrationId clientId : toRemove) { |
|||
mobileAppDao.removeOauth2Clients(mobileAppId, clientId); |
|||
} |
|||
for (MobileAppOauth2Registration mobileAppOauth2Registration : oauth2Clients) { |
|||
mobileAppDao.saveOauth2Clients(mobileAppOauth2Registration); |
|||
} |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId) |
|||
.entityId(mobileAppId).created(false).build()); |
|||
} |
|||
|
|||
@Override |
|||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) { |
|||
return Optional.ofNullable(findMobileAppById(tenantId, new MobileAppId(entityId.getId()))); |
|||
} |
|||
|
|||
@Override |
|||
public EntityType getEntityType() { |
|||
return EntityType.MOBILE_APP; |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
|||
MobileApp mobileApp = mobileAppDao.findById(tenantId, id.getId()); |
|||
if (mobileApp == null) { |
|||
return; |
|||
} |
|||
deleteMobileAppById(tenantId, mobileApp.getId()); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Table; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_COLUMN; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.DOMAIN_TABLE_NAME) |
|||
public class DomainEntity extends BaseSqlEntity<Domain> { |
|||
|
|||
@Column(name = TENANT_ID_COLUMN) |
|||
private UUID tenantId; |
|||
|
|||
@Column(name = ModelConstants.DOMAIN_DOMAIN_NAME_PROPERTY) |
|||
private String name; |
|||
|
|||
@Column(name = ModelConstants.DOMAIN_OAUTH2_ENABLED_PROPERTY) |
|||
private Boolean oauth2Enabled; |
|||
|
|||
@Column(name = ModelConstants.DOMAIN_PROPAGATE_TO_EDGE_PROPERTY) |
|||
private Boolean propagateToEdge; |
|||
|
|||
public DomainEntity(Domain domain) { |
|||
if (domain.getId() != null) { |
|||
this.setUuid(domain.getId().getId()); |
|||
} |
|||
if (domain.getTenantId() != null) { |
|||
this.tenantId = domain.getTenantId().getId(); |
|||
} |
|||
this.setCreatedTime(domain.getCreatedTime()); |
|||
this.name = domain.getName(); |
|||
this.oauth2Enabled = domain.isOauth2Enabled(); |
|||
this.propagateToEdge = domain.isPropagateToEdge(); |
|||
} |
|||
|
|||
public DomainEntity() { |
|||
super(); |
|||
} |
|||
|
|||
@Override |
|||
public Domain toData() { |
|||
Domain domain = new Domain(); |
|||
domain.setId(new DomainId(id)); |
|||
if (tenantId != null) { |
|||
domain.setTenantId(TenantId.fromUUID(tenantId)); |
|||
} |
|||
domain.setCreatedTime(createdTime); |
|||
domain.setName(name); |
|||
domain.setOauth2Enabled(oauth2Enabled); |
|||
domain.setPropagateToEdge(propagateToEdge); |
|||
return domain; |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Transient; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.UUID; |
|||
|
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Data |
|||
public class DomainOauth2RegistrationCompositeKey implements Serializable { |
|||
|
|||
@Transient |
|||
private static final long serialVersionUID = -245388185894468455L; |
|||
|
|||
private UUID domainId; |
|||
private UUID oauth2RegistrationId; |
|||
|
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.IdClass; |
|||
import jakarta.persistence.Table; |
|||
import lombok.Data; |
|||
import org.thingsboard.server.common.data.domain.DomainOauth2Registration; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
import org.thingsboard.server.dao.model.ToData; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.dao.model.ModelConstants.DOMAIN_OAUTH2_PROVIDER_DOMAIN_ID_PROPERTY; |
|||
import static org.thingsboard.server.dao.model.ModelConstants.DOMAIN_OAUTH2_REGISTRATION_TABLE_NAME; |
|||
|
|||
@Data |
|||
@Entity |
|||
@Table(name = DOMAIN_OAUTH2_REGISTRATION_TABLE_NAME) |
|||
@IdClass(DomainOauth2RegistrationCompositeKey.class) |
|||
public final class DomainOauth2RegistrationEntity implements ToData<DomainOauth2Registration> { |
|||
|
|||
@Id |
|||
@Column(name = DOMAIN_OAUTH2_PROVIDER_DOMAIN_ID_PROPERTY, columnDefinition = "uuid") |
|||
private UUID domainId; |
|||
|
|||
@Id |
|||
@Column(name = ModelConstants.DOMAIN_OAUTH2_PROVIDER_PROVIDER_ID_PROPERTY, columnDefinition = "uuid") |
|||
private UUID oauth2RegistrationId; |
|||
|
|||
|
|||
public DomainOauth2RegistrationEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public DomainOauth2RegistrationEntity(DomainOauth2Registration domainOauth2Registration) { |
|||
domainId = domainOauth2Registration.getDomainId().getId(); |
|||
oauth2RegistrationId = domainOauth2Registration.getOAuth2RegistrationId().getId(); |
|||
} |
|||
|
|||
@Override |
|||
public DomainOauth2Registration toData() { |
|||
DomainOauth2Registration result = new DomainOauth2Registration(); |
|||
result.setDomainId(new DomainId(domainId)); |
|||
result.setOAuth2RegistrationId(new OAuth2RegistrationId(oauth2RegistrationId)); |
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Transient; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.UUID; |
|||
|
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Data |
|||
public class MobileAppOauth2RegistrationCompositeKey implements Serializable { |
|||
|
|||
@Transient |
|||
private static final long serialVersionUID = -245388185894468455L; |
|||
|
|||
private UUID mobileAppId; |
|||
private UUID oauth2RegistrationId; |
|||
|
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.IdClass; |
|||
import jakarta.persistence.Table; |
|||
import lombok.Data; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Registration; |
|||
import org.thingsboard.server.dao.model.ToData; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_REGISTRATION_MOBILE_APP_ID_PROPERTY; |
|||
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_REGISTRATION_REGISTRATION_ID_PROPERTY; |
|||
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_REGISTRATION_TABLE_NAME; |
|||
|
|||
@Data |
|||
@Entity |
|||
@Table(name = MOBILE_APP_OAUTH2_REGISTRATION_TABLE_NAME) |
|||
@IdClass(MobileAppOauth2RegistrationCompositeKey.class) |
|||
public final class MobileAppOauth2RegistrationEntity implements ToData<MobileAppOauth2Registration> { |
|||
|
|||
@Id |
|||
@Column(name = MOBILE_APP_OAUTH2_REGISTRATION_MOBILE_APP_ID_PROPERTY, columnDefinition = "uuid") |
|||
private UUID mobileAppId; |
|||
|
|||
@Id |
|||
@Column(name = MOBILE_APP_OAUTH2_REGISTRATION_REGISTRATION_ID_PROPERTY, columnDefinition = "uuid") |
|||
private UUID oauth2RegistrationId; |
|||
|
|||
|
|||
public MobileAppOauth2RegistrationEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public MobileAppOauth2RegistrationEntity(MobileAppOauth2Registration domainOauth2Provider) { |
|||
mobileAppId = domainOauth2Provider.getMobileAppId().getId(); |
|||
oauth2RegistrationId = domainOauth2Provider.getOAuth2RegistrationId().getId(); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public MobileAppOauth2Registration toData() { |
|||
MobileAppOauth2Registration result = new MobileAppOauth2Registration(); |
|||
result.setMobileAppId(new MobileAppId(mobileAppId)); |
|||
result.setOAuth2RegistrationId(new OAuth2RegistrationId(oauth2RegistrationId)); |
|||
return result; |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.id.OAuth2DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.EnumType; |
|||
import jakarta.persistence.Enumerated; |
|||
import jakarta.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.OAUTH2_DOMAIN_TABLE_NAME) |
|||
public class OAuth2DomainEntity extends BaseSqlEntity<OAuth2Domain> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ID_PROPERTY) |
|||
private UUID oauth2ParamsId; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_DOMAIN_NAME_PROPERTY) |
|||
private String domainName; |
|||
|
|||
@Enumerated(EnumType.STRING) |
|||
@Column(name = ModelConstants.OAUTH2_DOMAIN_SCHEME_PROPERTY) |
|||
private SchemeType domainScheme; |
|||
|
|||
public OAuth2DomainEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public OAuth2DomainEntity(OAuth2Domain domain) { |
|||
if (domain.getId() != null) { |
|||
this.setUuid(domain.getId().getId()); |
|||
} |
|||
this.setCreatedTime(domain.getCreatedTime()); |
|||
if (domain.getOauth2ParamsId() != null) { |
|||
this.oauth2ParamsId = domain.getOauth2ParamsId().getId(); |
|||
} |
|||
this.domainName = domain.getDomainName(); |
|||
this.domainScheme = domain.getDomainScheme(); |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Domain toData() { |
|||
OAuth2Domain domain = new OAuth2Domain(); |
|||
domain.setId(new OAuth2DomainId(id)); |
|||
domain.setCreatedTime(createdTime); |
|||
domain.setOauth2ParamsId(new OAuth2ParamsId(oauth2ParamsId)); |
|||
domain.setDomainName(domainName); |
|||
domain.setDomainScheme(domainScheme); |
|||
return domain; |
|||
} |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.OAUTH2_PARAMS_TABLE_NAME) |
|||
@NoArgsConstructor |
|||
public class OAuth2ParamsEntity extends BaseSqlEntity<OAuth2Params> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ENABLED_PROPERTY) |
|||
private Boolean enabled; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_EDGE_ENABLED_PROPERTY) |
|||
private Boolean edgeEnabled; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_TENANT_ID_PROPERTY) |
|||
private UUID tenantId; |
|||
|
|||
public OAuth2ParamsEntity(OAuth2Params oauth2Params) { |
|||
if (oauth2Params.getId() != null) { |
|||
this.setUuid(oauth2Params.getUuidId()); |
|||
} |
|||
this.setCreatedTime(oauth2Params.getCreatedTime()); |
|||
this.enabled = oauth2Params.isEnabled(); |
|||
this.edgeEnabled = oauth2Params.isEdgeEnabled(); |
|||
if (oauth2Params.getTenantId() != null) { |
|||
this.tenantId = oauth2Params.getTenantId().getId(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Params toData() { |
|||
OAuth2Params oauth2Params = new OAuth2Params(); |
|||
oauth2Params.setId(new OAuth2ParamsId(id)); |
|||
oauth2Params.setCreatedTime(createdTime); |
|||
oauth2Params.setTenantId(TenantId.fromUUID(tenantId)); |
|||
oauth2Params.setEnabled(enabled); |
|||
oauth2Params.setEdgeEnabled(edgeEnabled); |
|||
return oauth2Params; |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import jakarta.persistence.Entity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.UUID; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
public class OAuth2RegistrationInfoEntity extends BaseSqlEntity<OAuth2RegistrationInfo> { |
|||
|
|||
private String platforms; |
|||
private String title; |
|||
|
|||
public OAuth2RegistrationInfoEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public OAuth2RegistrationInfoEntity(UUID id, long createdTime, String platforms, String title) { |
|||
this.id = id; |
|||
this.createdTime = createdTime; |
|||
this.platforms = platforms; |
|||
this.title = title; |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2RegistrationInfo toData() { |
|||
OAuth2RegistrationInfo oAuth2RegistrationInfo = new OAuth2RegistrationInfo(); |
|||
oAuth2RegistrationInfo.setId(new OAuth2RegistrationId(id)); |
|||
oAuth2RegistrationInfo.setCreatedTime(createdTime); |
|||
oAuth2RegistrationInfo.setTitle(title); |
|||
oAuth2RegistrationInfo.setPlatforms(StringUtils.isNotEmpty(platforms) ? Arrays.stream(platforms.split(",")) |
|||
.map(str -> PlatformType.valueOf(str)).collect(Collectors.toList()) : Collections.emptyList()); |
|||
return oAuth2RegistrationInfo; |
|||
} |
|||
} |
|||
@ -0,0 +1,145 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import jakarta.transaction.Transactional; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.HasId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; |
|||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
|
|||
import java.util.List; |
|||
import java.util.Optional; |
|||
import java.util.UUID; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import static org.thingsboard.server.dao.service.Validator.validateId; |
|||
import static org.thingsboard.server.dao.service.Validator.validateString; |
|||
|
|||
@Slf4j |
|||
@Service |
|||
public class OAuth2ClientServiceImpl extends AbstractEntityService implements OAuth2ClientService { |
|||
|
|||
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|||
public static final String INCORRECT_CLIENT_REGISTRATION_ID = "Incorrect clientRegistrationId "; |
|||
public static final String INCORRECT_DOMAIN_NAME = "Incorrect domainName "; |
|||
|
|||
@Autowired |
|||
private OAuth2RegistrationDao oauth2RegistrationDao; |
|||
@Autowired |
|||
private DataValidator<OAuth2Registration> oAuth2RegistrationDataValidator; |
|||
|
|||
@Override |
|||
public List<OAuth2ClientInfo> getWebOAuth2Clients(String domainName, PlatformType platformType) { |
|||
log.trace("Executing getOAuth2Clients [{}] ", domainName); |
|||
validateString(domainName, dn -> INCORRECT_DOMAIN_NAME + dn); |
|||
return oauth2RegistrationDao.findEnabledByDomainNameAndPlatformType(domainName, platformType) |
|||
.stream() |
|||
.map(OAuth2Utils::toClientInfo) |
|||
.collect(Collectors.toList()); |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2ClientInfo> getMobileOAuth2Clients(String pkgName, PlatformType platformType) { |
|||
log.trace("Executing getOAuth2Clients pkgName=[{}] platformType=[{}]",pkgName, platformType); |
|||
return oauth2RegistrationDao.findEnabledByPckNameAndPlatformType(pkgName, platformType) |
|||
.stream() |
|||
.map(OAuth2Utils::toClientInfo) |
|||
.collect(Collectors.toList()); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public OAuth2Registration saveOAuth2Client(TenantId tenantId, OAuth2Registration oAuth2Registration) { |
|||
log.trace("Executing saveOAuth2Client [{}]", oAuth2Registration); |
|||
oAuth2RegistrationDataValidator.validate(oAuth2Registration, OAuth2Registration::getTenantId); |
|||
OAuth2Registration savedOauth2Registration = oauth2RegistrationDao.save(tenantId, oAuth2Registration); |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(TenantId.SYS_TENANT_ID).entity(oAuth2Registration).build()); |
|||
return savedOauth2Registration; |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Registration findOAuth2ClientById(TenantId tenantId, OAuth2RegistrationId oAuth2RegistrationId) { |
|||
log.trace("Executing findOAuth2ClientById [{}]", oAuth2RegistrationId); |
|||
validateId(oAuth2RegistrationId, uuid -> INCORRECT_CLIENT_REGISTRATION_ID + uuid); |
|||
return oauth2RegistrationDao.findById(tenantId, oAuth2RegistrationId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2RegistrationInfo> findOauth2ClientInfosByTenantId(TenantId tenantId) { |
|||
log.trace("Executing findOauth2ClientInfosByTenantId"); |
|||
return oauth2RegistrationDao.findInfosByTenantId(tenantId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Registration> findOauth2ClientsByTenantId(TenantId tenantId) { |
|||
log.trace("Executing findOauth2ClientsByTenantId [{}]", tenantId); |
|||
return oauth2RegistrationDao.findByTenantId(tenantId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public String findAppSecret(UUID id, String pkgName) { |
|||
log.trace("Executing findAppSecret [{}][{}]", id, pkgName); |
|||
validateId(id, uuid -> INCORRECT_CLIENT_REGISTRATION_ID + uuid); |
|||
validateString(pkgName, "Incorrect package name"); |
|||
return oauth2RegistrationDao.findAppSecret(id, pkgName); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void deleteById(TenantId tenantId, OAuth2RegistrationId oAuth2RegistrationId) { |
|||
log.trace("[{}][{}] Executing deleteById [{}]", tenantId, oAuth2RegistrationId); |
|||
oauth2RegistrationDao.removeById(tenantId, oAuth2RegistrationId.getId()); |
|||
eventPublisher.publishEvent(DeleteEntityEvent.builder() |
|||
.tenantId(tenantId) |
|||
.entityId(oAuth2RegistrationId) |
|||
.build()); |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) { |
|||
return Optional.ofNullable(findOAuth2ClientById(tenantId, new OAuth2RegistrationId(entityId.getId()))); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
|||
OAuth2Registration oAuth2Registration = oauth2RegistrationDao.findById(tenantId, id.getId()); |
|||
if (oAuth2Registration == null) { |
|||
return; |
|||
} |
|||
deleteById(tenantId, oAuth2Registration.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public EntityType getEntityType() { |
|||
return EntityType.OAUTH2_CLIENT; |
|||
} |
|||
|
|||
} |
|||
@ -1,295 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.collections4.CollectionUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.MapperType; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2BasicMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2DomainInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Mobile; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MobileInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ParamsInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.common.data.oauth2.TenantNameStrategyType; |
|||
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.exception.IncorrectParameterException; |
|||
|
|||
import jakarta.transaction.Transactional; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Comparator; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
import java.util.function.Consumer; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import static org.thingsboard.server.dao.service.Validator.validateId; |
|||
import static org.thingsboard.server.dao.service.Validator.validateString; |
|||
|
|||
@Slf4j |
|||
@Service |
|||
public class OAuth2ServiceImpl extends AbstractEntityService implements OAuth2Service { |
|||
|
|||
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|||
public static final String INCORRECT_CLIENT_REGISTRATION_ID = "Incorrect clientRegistrationId "; |
|||
public static final String INCORRECT_DOMAIN_NAME = "Incorrect domainName "; |
|||
public static final String INCORRECT_DOMAIN_SCHEME = "Incorrect domainScheme "; |
|||
|
|||
@Autowired |
|||
private OAuth2ParamsDao oauth2ParamsDao; |
|||
@Autowired |
|||
private OAuth2RegistrationDao oauth2RegistrationDao; |
|||
@Autowired |
|||
private OAuth2DomainDao oauth2DomainDao; |
|||
@Autowired |
|||
private OAuth2MobileDao oauth2MobileDao; |
|||
|
|||
@Override |
|||
public List<OAuth2ClientInfo> getOAuth2Clients(String domainSchemeStr, String domainName, String pkgName, PlatformType platformType) { |
|||
log.trace("Executing getOAuth2Clients [{}://{}] pkgName=[{}] platformType=[{}]", domainSchemeStr, domainName, pkgName, platformType); |
|||
if (domainSchemeStr == null) { |
|||
throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); |
|||
} |
|||
SchemeType domainScheme; |
|||
try { |
|||
domainScheme = SchemeType.valueOf(domainSchemeStr.toUpperCase()); |
|||
} catch (IllegalArgumentException e){ |
|||
throw new IncorrectParameterException(INCORRECT_DOMAIN_SCHEME); |
|||
} |
|||
validateString(domainName, dn -> INCORRECT_DOMAIN_NAME + dn); |
|||
return oauth2RegistrationDao.findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType( |
|||
Arrays.asList(domainScheme, SchemeType.MIXED), domainName, pkgName, platformType) |
|||
.stream() |
|||
.map(OAuth2Utils::toClientInfo) |
|||
.collect(Collectors.toList()); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public void saveOAuth2Info(OAuth2Info oauth2Info) { |
|||
log.trace("Executing saveOAuth2Info [{}]", oauth2Info); |
|||
oauth2InfoValidator.accept(oauth2Info); |
|||
oauth2ParamsDao.deleteAll(); |
|||
oauth2Info.getOauth2ParamsInfos().forEach(oauth2ParamsInfo -> { |
|||
OAuth2Params oauth2Params = OAuth2Utils.infoToOAuth2Params(oauth2Info); |
|||
OAuth2Params savedOauth2Params = oauth2ParamsDao.save(TenantId.SYS_TENANT_ID, oauth2Params); |
|||
oauth2ParamsInfo.getClientRegistrations().forEach(registrationInfo -> { |
|||
OAuth2Registration registration = OAuth2Utils.toOAuth2Registration(savedOauth2Params.getId(), registrationInfo); |
|||
oauth2RegistrationDao.save(TenantId.SYS_TENANT_ID, registration); |
|||
}); |
|||
oauth2ParamsInfo.getDomainInfos().forEach(domainInfo -> { |
|||
OAuth2Domain domain = OAuth2Utils.toOAuth2Domain(savedOauth2Params.getId(), domainInfo); |
|||
oauth2DomainDao.save(TenantId.SYS_TENANT_ID, domain); |
|||
}); |
|||
if (oauth2ParamsInfo.getMobileInfos() != null) { |
|||
oauth2ParamsInfo.getMobileInfos().forEach(mobileInfo -> { |
|||
OAuth2Mobile mobile = OAuth2Utils.toOAuth2Mobile(savedOauth2Params.getId(), mobileInfo); |
|||
oauth2MobileDao.save(TenantId.SYS_TENANT_ID, mobile); |
|||
}); |
|||
} |
|||
}); |
|||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(TenantId.SYS_TENANT_ID).entity(oauth2Info).build()); |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Info findOAuth2Info() { |
|||
log.trace("Executing findOAuth2Info"); |
|||
OAuth2Info oauth2Info = new OAuth2Info(); |
|||
List<OAuth2Params> oauth2ParamsList = oauth2ParamsDao.find(TenantId.SYS_TENANT_ID); |
|||
oauth2Info.setEnabled(oauth2ParamsList.stream().anyMatch(OAuth2Params::isEnabled)); |
|||
oauth2Info.setEdgeEnabled(oauth2ParamsList.stream().anyMatch(OAuth2Params::isEdgeEnabled)); |
|||
List<OAuth2ParamsInfo> oauth2ParamsInfos = new ArrayList<>(); |
|||
oauth2Info.setOauth2ParamsInfos(oauth2ParamsInfos); |
|||
oauth2ParamsList.stream().sorted(Comparator.comparing(BaseData::getUuidId)).forEach(oauth2Params -> { |
|||
List<OAuth2Registration> registrations = oauth2RegistrationDao.findByOAuth2ParamsId(oauth2Params.getId().getId()); |
|||
List<OAuth2Domain> domains = oauth2DomainDao.findByOAuth2ParamsId(oauth2Params.getId().getId()); |
|||
List<OAuth2Mobile> mobiles = oauth2MobileDao.findByOAuth2ParamsId(oauth2Params.getId().getId()); |
|||
oauth2ParamsInfos.add(OAuth2Utils.toOAuth2ParamsInfo(registrations, domains, mobiles)); |
|||
}); |
|||
return oauth2Info; |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Registration findRegistration(UUID id) { |
|||
log.trace("Executing findRegistration [{}]", id); |
|||
validateId(id, uuid -> INCORRECT_CLIENT_REGISTRATION_ID + uuid); |
|||
return oauth2RegistrationDao.findById(null, id); |
|||
} |
|||
|
|||
@Override |
|||
public String findAppSecret(UUID id, String pkgName) { |
|||
log.trace("Executing findAppSecret [{}][{}]", id, pkgName); |
|||
validateId(id, uuid -> INCORRECT_CLIENT_REGISTRATION_ID + uuid); |
|||
validateString(pkgName, "Incorrect package name"); |
|||
return oauth2RegistrationDao.findAppSecret(id, pkgName); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public List<OAuth2Registration> findAllRegistrations() { |
|||
log.trace("Executing findAllRegistrations"); |
|||
return oauth2RegistrationDao.find(TenantId.SYS_TENANT_ID); |
|||
} |
|||
|
|||
private final Consumer<OAuth2Info> oauth2InfoValidator = oauth2Info -> { |
|||
if (oauth2Info == null |
|||
|| oauth2Info.getOauth2ParamsInfos() == null) { |
|||
throw new DataValidationException("OAuth2 param infos should be specified!"); |
|||
} |
|||
for (OAuth2ParamsInfo oauth2Params : oauth2Info.getOauth2ParamsInfos()) { |
|||
if (oauth2Params.getDomainInfos() == null |
|||
|| oauth2Params.getDomainInfos().isEmpty()) { |
|||
throw new DataValidationException("List of domain configuration should be specified!"); |
|||
} |
|||
for (OAuth2DomainInfo domainInfo : oauth2Params.getDomainInfos()) { |
|||
if (StringUtils.isEmpty(domainInfo.getName())) { |
|||
throw new DataValidationException("Domain name should be specified!"); |
|||
} |
|||
if (domainInfo.getScheme() == null) { |
|||
throw new DataValidationException("Domain scheme should be specified!"); |
|||
} |
|||
} |
|||
oauth2Params.getDomainInfos().stream() |
|||
.collect(Collectors.groupingBy(OAuth2DomainInfo::getName)) |
|||
.forEach((domainName, domainInfos) -> { |
|||
if (domainInfos.size() > 1 && domainInfos.stream().anyMatch(domainInfo -> domainInfo.getScheme() == SchemeType.MIXED)) { |
|||
throw new DataValidationException("MIXED scheme type shouldn't be combined with another scheme type!"); |
|||
} |
|||
domainInfos.stream() |
|||
.collect(Collectors.groupingBy(OAuth2DomainInfo::getScheme)) |
|||
.forEach((schemeType, domainInfosBySchemeType) -> { |
|||
if (domainInfosBySchemeType.size() > 1) { |
|||
throw new DataValidationException("Domain name and protocol must be unique within OAuth2 parameters!"); |
|||
} |
|||
}); |
|||
}); |
|||
if (oauth2Params.getMobileInfos() != null) { |
|||
for (OAuth2MobileInfo mobileInfo : oauth2Params.getMobileInfos()) { |
|||
if (StringUtils.isEmpty(mobileInfo.getPkgName())) { |
|||
throw new DataValidationException("Package should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(mobileInfo.getAppSecret())) { |
|||
throw new DataValidationException("Application secret should be specified!"); |
|||
} |
|||
if (mobileInfo.getAppSecret().length() < 16) { |
|||
throw new DataValidationException("Application secret should be at least 16 characters!"); |
|||
} |
|||
} |
|||
oauth2Params.getMobileInfos().stream() |
|||
.collect(Collectors.groupingBy(OAuth2MobileInfo::getPkgName)) |
|||
.forEach((pkgName, mobileInfos) -> { |
|||
if (mobileInfos.size() > 1) { |
|||
throw new DataValidationException("Mobile app package name must be unique within OAuth2 parameters!"); |
|||
} |
|||
}); |
|||
} |
|||
if (oauth2Params.getClientRegistrations() == null || oauth2Params.getClientRegistrations().isEmpty()) { |
|||
throw new DataValidationException("Client registrations should be specified!"); |
|||
} |
|||
for (OAuth2RegistrationInfo clientRegistration : oauth2Params.getClientRegistrations()) { |
|||
if (StringUtils.isEmpty(clientRegistration.getClientId())) { |
|||
throw new DataValidationException("Client ID should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getClientSecret())) { |
|||
throw new DataValidationException("Client secret should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getAuthorizationUri())) { |
|||
throw new DataValidationException("Authorization uri should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getAccessTokenUri())) { |
|||
throw new DataValidationException("Token uri should be specified!"); |
|||
} |
|||
if (CollectionUtils.isEmpty(clientRegistration.getScope())) { |
|||
throw new DataValidationException("Scope should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getUserNameAttributeName())) { |
|||
throw new DataValidationException("User name attribute name should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getClientAuthenticationMethod())) { |
|||
throw new DataValidationException("Client authentication method should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(clientRegistration.getLoginButtonLabel())) { |
|||
throw new DataValidationException("Login button label should be specified!"); |
|||
} |
|||
OAuth2MapperConfig mapperConfig = clientRegistration.getMapperConfig(); |
|||
if (mapperConfig == null) { |
|||
throw new DataValidationException("Mapper config should be specified!"); |
|||
} |
|||
if (mapperConfig.getType() == null) { |
|||
throw new DataValidationException("Mapper config type should be specified!"); |
|||
} |
|||
if (mapperConfig.getType() == MapperType.BASIC) { |
|||
OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic(); |
|||
if (basicConfig == null) { |
|||
throw new DataValidationException("Basic config should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(basicConfig.getEmailAttributeKey())) { |
|||
throw new DataValidationException("Email attribute key should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == null) { |
|||
throw new DataValidationException("Tenant name strategy should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == TenantNameStrategyType.CUSTOM |
|||
&& StringUtils.isEmpty(basicConfig.getTenantNamePattern())) { |
|||
throw new DataValidationException("Tenant name pattern should be specified!"); |
|||
} |
|||
} |
|||
if (mapperConfig.getType() == MapperType.GITHUB) { |
|||
OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic(); |
|||
if (basicConfig == null) { |
|||
throw new DataValidationException("Basic config should be specified!"); |
|||
} |
|||
if (!StringUtils.isEmpty(basicConfig.getEmailAttributeKey())) { |
|||
throw new DataValidationException("Email attribute key cannot be configured for GITHUB mapper type!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == null) { |
|||
throw new DataValidationException("Tenant name strategy should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == TenantNameStrategyType.CUSTOM |
|||
&& StringUtils.isEmpty(basicConfig.getTenantNamePattern())) { |
|||
throw new DataValidationException("Tenant name pattern should be specified!"); |
|||
} |
|||
} |
|||
if (mapperConfig.getType() == MapperType.CUSTOM) { |
|||
OAuth2CustomMapperConfig customConfig = mapperConfig.getCustom(); |
|||
if (customConfig == null) { |
|||
throw new DataValidationException("Custom config should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(customConfig.getUrl())) { |
|||
throw new DataValidationException("Custom mapper URL should be specified!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service.validator; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
|
|||
@Component |
|||
@AllArgsConstructor |
|||
public class DomainDataValidator extends DataValidator<Domain> { |
|||
|
|||
@Override |
|||
protected void validateDataImpl(TenantId tenantId, Domain domain) { |
|||
if (StringUtils.isEmpty(domain.getName())) { |
|||
throw new DataValidationException("Domain name should be specified!"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service.validator; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
|
|||
@Component |
|||
@AllArgsConstructor |
|||
public class MobileAppDataValidator extends DataValidator<MobileApp> { |
|||
|
|||
@Override |
|||
protected void validateDataImpl(TenantId tenantId, MobileApp mobileApp) { |
|||
if (StringUtils.isEmpty(mobileApp.getPkgName())) { |
|||
throw new DataValidationException("Package should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(mobileApp.getAppSecret())) { |
|||
throw new DataValidationException("Application secret should be specified!"); |
|||
} |
|||
if (mobileApp.getAppSecret().length() < 16) { |
|||
throw new DataValidationException("Application secret should be at least 16 characters!"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service.validator; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.apache.commons.collections4.CollectionUtils; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.MapperType; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2BasicMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.TenantNameStrategyType; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
|
|||
@Component |
|||
@AllArgsConstructor |
|||
public class Oauth2RegistrationDataValidator extends DataValidator<OAuth2Registration> { |
|||
|
|||
@Override |
|||
protected void validateDataImpl(TenantId tenantId, OAuth2Registration oAuth2Registration) { |
|||
if (StringUtils.isEmpty(oAuth2Registration.getClientId())) { |
|||
throw new DataValidationException("Client ID should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getClientId())) { |
|||
throw new DataValidationException("Client ID should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getClientSecret())) { |
|||
throw new DataValidationException("Client secret should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getAuthorizationUri())) { |
|||
throw new DataValidationException("Authorization uri should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getAccessTokenUri())) { |
|||
throw new DataValidationException("Token uri should be specified!"); |
|||
} |
|||
if (CollectionUtils.isEmpty(oAuth2Registration.getScope())) { |
|||
throw new DataValidationException("Scope should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getUserNameAttributeName())) { |
|||
throw new DataValidationException("User name attribute name should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getClientAuthenticationMethod())) { |
|||
throw new DataValidationException("Client authentication method should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(oAuth2Registration.getLoginButtonLabel())) { |
|||
throw new DataValidationException("Login button label should be specified!"); |
|||
} |
|||
OAuth2MapperConfig mapperConfig = oAuth2Registration.getMapperConfig(); |
|||
if (mapperConfig == null) { |
|||
throw new DataValidationException("Mapper config should be specified!"); |
|||
} |
|||
if (mapperConfig.getType() == null) { |
|||
throw new DataValidationException("Mapper config type should be specified!"); |
|||
} |
|||
if (mapperConfig.getType() == MapperType.BASIC) { |
|||
OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic(); |
|||
if (basicConfig == null) { |
|||
throw new DataValidationException("Basic config should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(basicConfig.getEmailAttributeKey())) { |
|||
throw new DataValidationException("Email attribute key should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == null) { |
|||
throw new DataValidationException("Tenant name strategy should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == TenantNameStrategyType.CUSTOM |
|||
&& StringUtils.isEmpty(basicConfig.getTenantNamePattern())) { |
|||
throw new DataValidationException("Tenant name pattern should be specified!"); |
|||
} |
|||
} |
|||
if (mapperConfig.getType() == MapperType.GITHUB) { |
|||
OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic(); |
|||
if (basicConfig == null) { |
|||
throw new DataValidationException("Basic config should be specified!"); |
|||
} |
|||
if (!StringUtils.isEmpty(basicConfig.getEmailAttributeKey())) { |
|||
throw new DataValidationException("Email attribute key cannot be configured for GITHUB mapper type!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == null) { |
|||
throw new DataValidationException("Tenant name strategy should be specified!"); |
|||
} |
|||
if (basicConfig.getTenantNameStrategy() == TenantNameStrategyType.CUSTOM |
|||
&& StringUtils.isEmpty(basicConfig.getTenantNamePattern())) { |
|||
throw new DataValidationException("Tenant name pattern should be specified!"); |
|||
} |
|||
} |
|||
if (mapperConfig.getType() == MapperType.CUSTOM) { |
|||
OAuth2CustomMapperConfig customConfig = mapperConfig.getCustom(); |
|||
if (customConfig == null) { |
|||
throw new DataValidationException("Custom config should be specified!"); |
|||
} |
|||
if (StringUtils.isEmpty(customConfig.getUrl())) { |
|||
throw new DataValidationException("Custom mapper URL should be specified!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.domain; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.Modifying; |
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.data.repository.query.Param; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.dao.model.sql.DomainOauth2RegistrationCompositeKey; |
|||
import org.thingsboard.server.dao.model.sql.DomainOauth2RegistrationEntity; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2RegistrationEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface DomainOauth2RegistrationRepository extends JpaRepository<DomainOauth2RegistrationEntity, DomainOauth2RegistrationCompositeKey> { |
|||
|
|||
List<DomainOauth2RegistrationEntity> findAllByDomainId(@Param("domainId") UUID domainId); |
|||
|
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.domain; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.Modifying; |
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.data.repository.query.Param; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.dao.model.sql.DomainEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface DomainRepository extends JpaRepository<DomainEntity, UUID> { |
|||
|
|||
List<DomainEntity> findByTenantId(@Param("tenantId") UUID tenantId); |
|||
|
|||
@Transactional |
|||
@Modifying |
|||
@Query("DELETE FROM MobileAppEntity r WHERE r.tenantId = :tenantId") |
|||
void deleteByTenantId(@Param("tenantId") UUID tenantId); |
|||
|
|||
int countByTenantIdAndOauth2Enabled(@Param("tenantId") UUID tenantId, @Param("oauth2Enabled") boolean oauth2Enabled); |
|||
|
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.domain; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.domain.Domain; |
|||
import org.thingsboard.server.common.data.domain.DomainOauth2Registration; |
|||
import org.thingsboard.server.common.data.id.DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.domain.DomainDao; |
|||
import org.thingsboard.server.dao.model.sql.DomainEntity; |
|||
import org.thingsboard.server.dao.model.sql.DomainOauth2RegistrationCompositeKey; |
|||
import org.thingsboard.server.dao.model.sql.DomainOauth2RegistrationEntity; |
|||
import org.thingsboard.server.dao.model.sql.WidgetsBundleWidgetEntity; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
@SqlDao |
|||
public class JpaDomainDao extends JpaAbstractDao<DomainEntity, Domain> implements DomainDao { |
|||
|
|||
private final DomainRepository domainRepository; |
|||
private final DomainOauth2RegistrationRepository domainOauth2RegistrationRepository; |
|||
|
|||
@Override |
|||
protected Class<DomainEntity> getEntityClass() { |
|||
return DomainEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<DomainEntity, UUID> getRepository() { |
|||
return domainRepository; |
|||
} |
|||
|
|||
@Override |
|||
public List<Domain> findByTenantId(TenantId tenantId) { |
|||
return DaoUtil.convertDataList(domainRepository.findByTenantId(tenantId.getId())); |
|||
} |
|||
|
|||
@Override |
|||
public int countDomainByTenantIdAndOauth2Enabled(TenantId tenantId, boolean enabled) { |
|||
return domainRepository.countByTenantIdAndOauth2Enabled(tenantId.getId(), enabled); |
|||
} |
|||
|
|||
@Override |
|||
public List<DomainOauth2Registration> findOauth2ClientsByDomainId(TenantId tenantId, DomainId domainId) { |
|||
return DaoUtil.convertDataList(domainOauth2RegistrationRepository.findAllByDomainId(domainId.getId())); |
|||
} |
|||
|
|||
@Override |
|||
public void saveOauth2Clients(DomainOauth2Registration domainOauth2Registration) { |
|||
domainOauth2RegistrationRepository.save(new DomainOauth2RegistrationEntity(domainOauth2Registration)); |
|||
} |
|||
|
|||
@Override |
|||
public void removeOauth2Clients(DomainId domainId, OAuth2RegistrationId oAuth2RegistrationId) { |
|||
domainOauth2RegistrationRepository.deleteById(new DomainOauth2RegistrationCompositeKey(domainId.getId(), oAuth2RegistrationId.getId())); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,77 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.mobile; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.id.MobileAppId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.mobile.MobileApp; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Registration; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.mobile.MobileAppDao; |
|||
import org.thingsboard.server.dao.model.sql.MobileAppEntity; |
|||
import org.thingsboard.server.dao.model.sql.MobileAppOauth2RegistrationCompositeKey; |
|||
import org.thingsboard.server.dao.model.sql.MobileAppOauth2RegistrationEntity; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
@SqlDao |
|||
public class JpaMobileAppDao extends JpaAbstractDao<MobileAppEntity, MobileApp> implements MobileAppDao { |
|||
|
|||
private final MobileAppRepository repository; |
|||
private final MobileAppOauth2RegistrationRepository mobileOauth2ProviderRepository; |
|||
|
|||
@Override |
|||
protected Class<MobileAppEntity> getEntityClass() { |
|||
return MobileAppEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<MobileAppEntity, UUID> getRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<MobileApp> findByTenantId(TenantId tenantId) { |
|||
return DaoUtil.convertDataList(repository.findByTenantId(tenantId.getId())); |
|||
} |
|||
|
|||
@Override |
|||
public List<MobileAppOauth2Registration> findOauth2ClientsByMobileAppId(TenantId tenantId, MobileAppId mobileAppId) { |
|||
return DaoUtil.convertDataList(mobileOauth2ProviderRepository.findAllByMobileAppId(mobileAppId.getId())); |
|||
} |
|||
|
|||
@Override |
|||
public void saveOauth2Clients(MobileAppOauth2Registration mobileAppOauth2Registration) { |
|||
mobileOauth2ProviderRepository.save(new MobileAppOauth2RegistrationEntity(mobileAppOauth2Registration)); |
|||
} |
|||
|
|||
@Override |
|||
public void removeOauth2Clients(MobileAppId mobileAppId, OAuth2RegistrationId oAuth2RegistrationId) { |
|||
mobileOauth2ProviderRepository.deleteById(new MobileAppOauth2RegistrationCompositeKey(mobileAppId.getId(), oAuth2RegistrationId.getId())); |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,32 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.mobile; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.repository.query.Param; |
|||
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Registration; |
|||
import org.thingsboard.server.dao.model.sql.DomainOauth2RegistrationEntity; |
|||
import org.thingsboard.server.dao.model.sql.MobileAppOauth2RegistrationCompositeKey; |
|||
import org.thingsboard.server.dao.model.sql.MobileAppOauth2RegistrationEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface MobileAppOauth2RegistrationRepository extends JpaRepository<MobileAppOauth2RegistrationEntity, MobileAppOauth2RegistrationCompositeKey> { |
|||
|
|||
List<MobileAppOauth2RegistrationEntity> findAllByMobileAppId(@Param("mobileAppId") UUID mobileAppId); |
|||
|
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2DomainEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2DomainDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
@SqlDao |
|||
public class JpaOAuth2DomainDao extends JpaAbstractDao<OAuth2DomainEntity, OAuth2Domain> implements OAuth2DomainDao { |
|||
|
|||
private final OAuth2DomainRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2DomainEntity> getEntityClass() { |
|||
return OAuth2DomainEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<OAuth2DomainEntity, UUID> getRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Domain> findByOAuth2ParamsId(UUID oauth2ParamsId) { |
|||
return DaoUtil.convertDataList(repository.findByOauth2ParamsId(oauth2ParamsId)); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -1,54 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Mobile; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2MobileEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2MobileDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
@SqlDao |
|||
public class JpaOAuth2MobileDao extends JpaAbstractDao<OAuth2MobileEntity, OAuth2Mobile> implements OAuth2MobileDao { |
|||
|
|||
private final OAuth2MobileRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2MobileEntity> getEntityClass() { |
|||
return OAuth2MobileEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<OAuth2MobileEntity, UUID> getRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Mobile> findByOAuth2ParamsId(UUID oauth2ParamsId) { |
|||
return DaoUtil.convertDataList(repository.findByOauth2ParamsId(oauth2ParamsId)); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -1,49 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2ParamsEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2ParamsDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
@SqlDao |
|||
public class JpaOAuth2ParamsDao extends JpaAbstractDao<OAuth2ParamsEntity, OAuth2Params> implements OAuth2ParamsDao { |
|||
private final OAuth2ParamsRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2ParamsEntity> getEntityClass() { |
|||
return OAuth2ParamsEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<OAuth2ParamsEntity, UUID> getRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public void deleteAll() { |
|||
repository.deleteAll(); |
|||
} |
|||
} |
|||
@ -0,0 +1,641 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2ClientService; |
|||
|
|||
@DaoSqlTest |
|||
public class OAuth2ClientServiceTest extends AbstractServiceTest { |
|||
// private static final OAuth2Info EMPTY_PARAMS = new OAuth2Info(false, false, Collections.emptyList());
|
|||
|
|||
@Autowired |
|||
protected OAuth2ClientService oAuth2ClientService; |
|||
|
|||
// @Before
|
|||
// public void beforeRun() {
|
|||
// Assert.assertTrue(oAuth2Service.findOauth2ProvidersByTenantId().isEmpty());
|
|||
// }
|
|||
//
|
|||
// @After
|
|||
// public void after() {
|
|||
// oAuth2Service.saveOAuth2Info(EMPTY_PARAMS);
|
|||
// Assert.assertTrue(oAuth2Service.findOauth2ProvidersByTenantId().isEmpty());
|
|||
// Assert.assertTrue(oAuth2Service.findOAuth2Info().getOauth2ParamsInfos().isEmpty());
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testSaveHttpAndMixedDomainsTogether() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// Assertions.assertThrows(DataValidationException.class, () -> {
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// });
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testSaveHttpsAndMixedDomainsTogether() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build(),
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// Assertions.assertThrows(DataValidationException.class, () -> {
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// });
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testCreateAndFindParams() {
|
|||
// OAuth2Info oAuth2Info = createDefaultOAuth2Info();
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// // TODO ask if it's safe to check equality on AdditionalProperties
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testDisableParams() {
|
|||
// OAuth2Info oAuth2Info = createDefaultOAuth2Info();
|
|||
// oAuth2Info.setEnabled(true);
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// oAuth2Info.setEnabled(false);
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundDisabledOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertEquals(oAuth2Info, foundDisabledOAuth2Info);
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testClearDomainParams() {
|
|||
// OAuth2Info oAuth2Info = createDefaultOAuth2Info();
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(EMPTY_PARAMS);
|
|||
// OAuth2Info foundAfterClearClientsParams = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundAfterClearClientsParams);
|
|||
// Assert.assertEquals(EMPTY_PARAMS, foundAfterClearClientsParams);
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testUpdateClientsParams() {
|
|||
// OAuth2Info oAuth2Info = createDefaultOAuth2Info();
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// OAuth2Info newOAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("another-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("test-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// oAuth2Service.saveOAuth2Info(newOAuth2Info);
|
|||
// OAuth2Info foundAfterUpdateOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundAfterUpdateOAuth2Info);
|
|||
// Assert.assertEquals(newOAuth2Info, foundAfterUpdateOAuth2Info);
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testGetOAuth2Clients() {
|
|||
// List<OAuth2RegistrationInfo> firstGroup = Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// );
|
|||
// List<OAuth2RegistrationInfo> secondGroup = Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// );
|
|||
// List<OAuth2RegistrationInfo> thirdGroup = Lists.newArrayList(
|
|||
// validRegistrationInfo()
|
|||
// );
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(firstGroup)
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(secondGroup)
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
|
|||
// OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(thirdGroup)
|
|||
// .build()
|
|||
// ));
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstGroupClientInfos = firstGroup.stream()
|
|||
// .map(registrationInfo -> new OAuth2ClientInfo(
|
|||
// registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null))
|
|||
// .collect(Collectors.toList());
|
|||
// List<OAuth2ClientInfo> secondGroupClientInfos = secondGroup.stream()
|
|||
// .map(registrationInfo -> new OAuth2ClientInfo(
|
|||
// registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null))
|
|||
// .collect(Collectors.toList());
|
|||
// List<OAuth2ClientInfo> thirdGroupClientInfos = thirdGroup.stream()
|
|||
// .map(registrationInfo -> new OAuth2ClientInfo(
|
|||
// registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null))
|
|||
// .collect(Collectors.toList());
|
|||
//
|
|||
// List<OAuth2ClientInfo> nonExistentDomainClients = oAuth2Service.getOAuth2Clients("http", "non-existent-domain", null, null);
|
|||
// Assert.assertTrue(nonExistentDomainClients.isEmpty());
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null);
|
|||
// Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size());
|
|||
// firstGroupClientInfos.forEach(firstGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// firstDomainHttpClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(firstGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null);
|
|||
// Assert.assertTrue(firstDomainHttpsClients.isEmpty());
|
|||
//
|
|||
// List<OAuth2ClientInfo> fourthDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "fourth-domain", null, null);
|
|||
// Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpClients.size());
|
|||
// secondGroupClientInfos.forEach(secondGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// fourthDomainHttpClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(secondGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
// List<OAuth2ClientInfo> fourthDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "fourth-domain", null, null);
|
|||
// Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpsClients.size());
|
|||
// secondGroupClientInfos.forEach(secondGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// fourthDomainHttpsClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(secondGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
//
|
|||
// List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null);
|
|||
// Assert.assertEquals(firstGroupClientInfos.size() + secondGroupClientInfos.size(), secondDomainHttpClients.size());
|
|||
// firstGroupClientInfos.forEach(firstGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// secondDomainHttpClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(firstGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
// secondGroupClientInfos.forEach(secondGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// secondDomainHttpClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(secondGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(secondGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
//
|
|||
// List<OAuth2ClientInfo> secondDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "second-domain", null, null);
|
|||
// Assert.assertEquals(firstGroupClientInfos.size() + thirdGroupClientInfos.size(), secondDomainHttpsClients.size());
|
|||
// firstGroupClientInfos.forEach(firstGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// secondDomainHttpsClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(firstGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
// thirdGroupClientInfos.forEach(thirdGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// secondDomainHttpsClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(thirdGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(thirdGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testGetOAuth2ClientsForHttpAndHttps() {
|
|||
// List<OAuth2RegistrationInfo> firstGroup = Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// );
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(firstGroup)
|
|||
// .build()
|
|||
// ));
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertNotNull(foundOAuth2Info);
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstGroupClientInfos = firstGroup.stream()
|
|||
// .map(registrationInfo -> new OAuth2ClientInfo(
|
|||
// registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null))
|
|||
// .collect(Collectors.toList());
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null);
|
|||
// Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size());
|
|||
// firstGroupClientInfos.forEach(firstGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// firstDomainHttpClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(firstGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null);
|
|||
// Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpsClients.size());
|
|||
// firstGroupClientInfos.forEach(firstGroupClientInfo -> {
|
|||
// Assert.assertTrue(
|
|||
// firstDomainHttpsClients.stream().anyMatch(clientInfo ->
|
|||
// clientInfo.getIcon().equals(firstGroupClientInfo.getIcon())
|
|||
// && clientInfo.getName().equals(firstGroupClientInfo.getName()))
|
|||
// );
|
|||
// });
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testGetDisabledOAuth2Clients() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null);
|
|||
// Assert.assertEquals(5, secondDomainHttpClients.size());
|
|||
//
|
|||
// oAuth2Info.setEnabled(false);
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> secondDomainHttpDisabledClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null);
|
|||
// Assert.assertEquals(0, secondDomainHttpDisabledClients.size());
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testFindAllRegistrations() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
|
|||
// OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// List<OAuth2Provider> foundRegistrations = oAuth2Service.findOauth2ProvidersByTenantId();
|
|||
// Assert.assertEquals(6, foundRegistrations.size());
|
|||
// oAuth2Info.getOauth2ParamsInfos().stream()
|
|||
// .flatMap(paramsInfo -> paramsInfo.getClientRegistrations().stream())
|
|||
// .forEach(registrationInfo ->
|
|||
// Assert.assertTrue(
|
|||
// foundRegistrations.stream()
|
|||
// .anyMatch(registration -> registration.getClientId().equals(registrationInfo.getClientId()))
|
|||
// )
|
|||
// );
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testFindRegistrationById() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(),
|
|||
// OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build()
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
//
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
// List<OAuth2Provider> foundRegistrations = oAuth2Service.findOauth2ProvidersByTenantId();
|
|||
// foundRegistrations.forEach(registration -> {
|
|||
// OAuth2Provider foundRegistration = oAuth2Service.findProvider(registration.getUuidId());
|
|||
// Assert.assertEquals(registration, foundRegistration);
|
|||
// });
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testFindAppSecret() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Lists.newArrayList(
|
|||
// validMobileInfo("com.test.pkg1", "testPkg1AppSecret"),
|
|||
// validMobileInfo("com.test.pkg2", "testPkg2AppSecret")
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
//
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null);
|
|||
// Assert.assertEquals(3, firstDomainHttpClients.size());
|
|||
// for (OAuth2ClientInfo clientInfo : firstDomainHttpClients) {
|
|||
// String[] segments = clientInfo.getUrl().split("/");
|
|||
// String registrationId = segments[segments.length-1];
|
|||
// String appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg1");
|
|||
// Assert.assertNotNull(appSecret);
|
|||
// Assert.assertEquals("testPkg1AppSecret", appSecret);
|
|||
// appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg2");
|
|||
// Assert.assertNotNull(appSecret);
|
|||
// Assert.assertEquals("testPkg2AppSecret", appSecret);
|
|||
// appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg3");
|
|||
// Assert.assertNull(appSecret);
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// @Test
|
|||
// public void testFindClientsByPackageAndPlatform() {
|
|||
// OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Lists.newArrayList(
|
|||
// validMobileInfo("com.test.pkg1", "testPkg1Callback"),
|
|||
// validMobileInfo("com.test.pkg2", "testPkg2Callback")
|
|||
// ))
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo("Google", Arrays.asList(PlatformType.WEB, PlatformType.ANDROID)),
|
|||
// validRegistrationInfo("Facebook", Arrays.asList(PlatformType.IOS)),
|
|||
// validRegistrationInfo("GitHub", Collections.emptyList())
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// oAuth2Service.saveOAuth2Info(oAuth2Info);
|
|||
//
|
|||
// OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info();
|
|||
// Assert.assertEquals(oAuth2Info, foundOAuth2Info);
|
|||
//
|
|||
// List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null);
|
|||
// Assert.assertEquals(3, firstDomainHttpClients.size());
|
|||
// List<OAuth2ClientInfo> pkg1Clients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null);
|
|||
// Assert.assertEquals(3, pkg1Clients.size());
|
|||
// List<OAuth2ClientInfo> pkg1AndroidClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.ANDROID);
|
|||
// Assert.assertEquals(2, pkg1AndroidClients.size());
|
|||
// Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("Google")));
|
|||
// Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("GitHub")));
|
|||
// List<OAuth2ClientInfo> pkg1IOSClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.IOS);
|
|||
// Assert.assertEquals(2, pkg1IOSClients.size());
|
|||
// Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("Facebook")));
|
|||
// Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("GitHub")));
|
|||
// }
|
|||
//
|
|||
// private OAuth2Info createDefaultOAuth2Info() {
|
|||
// return new OAuth2Info(true, false, Lists.newArrayList(
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(),
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build(),
|
|||
// OAuth2ParamsInfo.builder()
|
|||
// .domainInfos(Lists.newArrayList(
|
|||
// OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(),
|
|||
// OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build()
|
|||
// ))
|
|||
// .mobileInfos(Collections.emptyList())
|
|||
// .clientRegistrations(Lists.newArrayList(
|
|||
// validRegistrationInfo(),
|
|||
// validRegistrationInfo()
|
|||
// ))
|
|||
// .build()
|
|||
// ));
|
|||
// }
|
|||
//
|
|||
// private OAuth2RegistrationInfo validRegistrationInfo() {
|
|||
// return validRegistrationInfo(null, Collections.emptyList());
|
|||
// }
|
|||
//
|
|||
// private OAuth2RegistrationInfo validRegistrationInfo(String label, List<PlatformType> platforms) {
|
|||
// return OAuth2RegistrationInfo.builder()
|
|||
// .clientId(UUID.randomUUID().toString())
|
|||
// .clientSecret(UUID.randomUUID().toString())
|
|||
// .authorizationUri(UUID.randomUUID().toString())
|
|||
// .accessTokenUri(UUID.randomUUID().toString())
|
|||
// .scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString()))
|
|||
// .platforms(platforms == null ? Collections.emptyList() : platforms)
|
|||
// .userInfoUri(UUID.randomUUID().toString())
|
|||
// .userNameAttributeName(UUID.randomUUID().toString())
|
|||
// .jwkSetUri(UUID.randomUUID().toString())
|
|||
// .clientAuthenticationMethod(UUID.randomUUID().toString())
|
|||
// .loginButtonLabel(label != null ? label : UUID.randomUUID().toString())
|
|||
// .loginButtonIcon(UUID.randomUUID().toString())
|
|||
// .additionalInfo(JacksonUtil.newObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString()))
|
|||
// .mapperConfig(
|
|||
// OAuth2MapperConfig.builder()
|
|||
// .allowUserCreation(true)
|
|||
// .activateUser(true)
|
|||
// .type(MapperType.CUSTOM)
|
|||
// .custom(
|
|||
// OAuth2CustomMapperConfig.builder()
|
|||
// .url(UUID.randomUUID().toString())
|
|||
// .build()
|
|||
// )
|
|||
// .build()
|
|||
// )
|
|||
// .build();
|
|||
// }
|
|||
//
|
|||
// private MobileAppInfo validMobileInfo(String pkgName, String appSecret) {
|
|||
// return MobileAppInfo.builder().pkgName(pkgName)
|
|||
// .appSecret(appSecret != null ? appSecret : StringUtils.randomAlphanumeric(24))
|
|||
// .build();
|
|||
// }
|
|||
|
|||
} |
|||
@ -1,668 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service; |
|||
|
|||
import com.google.common.collect.Lists; |
|||
import org.junit.After; |
|||
import org.junit.Assert; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.junit.jupiter.api.Assertions; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.oauth2.MapperType; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2DomainInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MobileInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ParamsInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2Service; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@DaoSqlTest |
|||
public class OAuth2ServiceTest extends AbstractServiceTest { |
|||
private static final OAuth2Info EMPTY_PARAMS = new OAuth2Info(false, false, Collections.emptyList()); |
|||
|
|||
@Autowired |
|||
protected OAuth2Service oAuth2Service; |
|||
|
|||
@Before |
|||
public void beforeRun() { |
|||
Assert.assertTrue(oAuth2Service.findAllRegistrations().isEmpty()); |
|||
} |
|||
|
|||
@After |
|||
public void after() { |
|||
oAuth2Service.saveOAuth2Info(EMPTY_PARAMS); |
|||
Assert.assertTrue(oAuth2Service.findAllRegistrations().isEmpty()); |
|||
Assert.assertTrue(oAuth2Service.findOAuth2Info().getOauth2ParamsInfos().isEmpty()); |
|||
} |
|||
|
|||
@Test |
|||
public void testSaveHttpAndMixedDomainsTogether() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
Assertions.assertThrows(DataValidationException.class, () -> { |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
}); |
|||
} |
|||
|
|||
@Test |
|||
public void testSaveHttpsAndMixedDomainsTogether() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build(), |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
Assertions.assertThrows(DataValidationException.class, () -> { |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
}); |
|||
} |
|||
|
|||
@Test |
|||
public void testCreateAndFindParams() { |
|||
OAuth2Info oAuth2Info = createDefaultOAuth2Info(); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
// TODO ask if it's safe to check equality on AdditionalProperties
|
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
} |
|||
|
|||
@Test |
|||
public void testDisableParams() { |
|||
OAuth2Info oAuth2Info = createDefaultOAuth2Info(); |
|||
oAuth2Info.setEnabled(true); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
oAuth2Info.setEnabled(false); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundDisabledOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertEquals(oAuth2Info, foundDisabledOAuth2Info); |
|||
} |
|||
|
|||
@Test |
|||
public void testClearDomainParams() { |
|||
OAuth2Info oAuth2Info = createDefaultOAuth2Info(); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
oAuth2Service.saveOAuth2Info(EMPTY_PARAMS); |
|||
OAuth2Info foundAfterClearClientsParams = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundAfterClearClientsParams); |
|||
Assert.assertEquals(EMPTY_PARAMS, foundAfterClearClientsParams); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateClientsParams() { |
|||
OAuth2Info oAuth2Info = createDefaultOAuth2Info(); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
OAuth2Info newOAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("another-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("test-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
oAuth2Service.saveOAuth2Info(newOAuth2Info); |
|||
OAuth2Info foundAfterUpdateOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundAfterUpdateOAuth2Info); |
|||
Assert.assertEquals(newOAuth2Info, foundAfterUpdateOAuth2Info); |
|||
} |
|||
|
|||
@Test |
|||
public void testGetOAuth2Clients() { |
|||
List<OAuth2RegistrationInfo> firstGroup = Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
); |
|||
List<OAuth2RegistrationInfo> secondGroup = Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
); |
|||
List<OAuth2RegistrationInfo> thirdGroup = Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
); |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(firstGroup) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(secondGroup) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), |
|||
OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(thirdGroup) |
|||
.build() |
|||
)); |
|||
|
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> firstGroupClientInfos = firstGroup.stream() |
|||
.map(registrationInfo -> new OAuth2ClientInfo( |
|||
registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
|||
.collect(Collectors.toList()); |
|||
List<OAuth2ClientInfo> secondGroupClientInfos = secondGroup.stream() |
|||
.map(registrationInfo -> new OAuth2ClientInfo( |
|||
registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
|||
.collect(Collectors.toList()); |
|||
List<OAuth2ClientInfo> thirdGroupClientInfos = thirdGroup.stream() |
|||
.map(registrationInfo -> new OAuth2ClientInfo( |
|||
registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
List<OAuth2ClientInfo> nonExistentDomainClients = oAuth2Service.getOAuth2Clients("http", "non-existent-domain", null, null); |
|||
Assert.assertTrue(nonExistentDomainClients.isEmpty()); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); |
|||
Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); |
|||
firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
firstDomainHttpClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(firstGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(firstGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null); |
|||
Assert.assertTrue(firstDomainHttpsClients.isEmpty()); |
|||
|
|||
List<OAuth2ClientInfo> fourthDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "fourth-domain", null, null); |
|||
Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpClients.size()); |
|||
secondGroupClientInfos.forEach(secondGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
fourthDomainHttpClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(secondGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(secondGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
List<OAuth2ClientInfo> fourthDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "fourth-domain", null, null); |
|||
Assert.assertEquals(secondGroupClientInfos.size(), fourthDomainHttpsClients.size()); |
|||
secondGroupClientInfos.forEach(secondGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
fourthDomainHttpsClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(secondGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(secondGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
|
|||
List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
|||
Assert.assertEquals(firstGroupClientInfos.size() + secondGroupClientInfos.size(), secondDomainHttpClients.size()); |
|||
firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
secondDomainHttpClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(firstGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(firstGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
secondGroupClientInfos.forEach(secondGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
secondDomainHttpClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(secondGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(secondGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
|
|||
List<OAuth2ClientInfo> secondDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "second-domain", null, null); |
|||
Assert.assertEquals(firstGroupClientInfos.size() + thirdGroupClientInfos.size(), secondDomainHttpsClients.size()); |
|||
firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
secondDomainHttpsClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(firstGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(firstGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
thirdGroupClientInfos.forEach(thirdGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
secondDomainHttpsClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(thirdGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(thirdGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
} |
|||
|
|||
@Test |
|||
public void testGetOAuth2ClientsForHttpAndHttps() { |
|||
List<OAuth2RegistrationInfo> firstGroup = Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
); |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(firstGroup) |
|||
.build() |
|||
)); |
|||
|
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertNotNull(foundOAuth2Info); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> firstGroupClientInfos = firstGroup.stream() |
|||
.map(registrationInfo -> new OAuth2ClientInfo( |
|||
registrationInfo.getLoginButtonLabel(), registrationInfo.getLoginButtonIcon(), null)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); |
|||
Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpClients.size()); |
|||
firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
firstDomainHttpClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(firstGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(firstGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpsClients = oAuth2Service.getOAuth2Clients("https", "first-domain", null, null); |
|||
Assert.assertEquals(firstGroupClientInfos.size(), firstDomainHttpsClients.size()); |
|||
firstGroupClientInfos.forEach(firstGroupClientInfo -> { |
|||
Assert.assertTrue( |
|||
firstDomainHttpsClients.stream().anyMatch(clientInfo -> |
|||
clientInfo.getIcon().equals(firstGroupClientInfo.getIcon()) |
|||
&& clientInfo.getName().equals(firstGroupClientInfo.getName())) |
|||
); |
|||
}); |
|||
} |
|||
|
|||
@Test |
|||
public void testGetDisabledOAuth2Clients() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
|
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> secondDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
|||
Assert.assertEquals(5, secondDomainHttpClients.size()); |
|||
|
|||
oAuth2Info.setEnabled(false); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> secondDomainHttpDisabledClients = oAuth2Service.getOAuth2Clients("http", "second-domain", null, null); |
|||
Assert.assertEquals(0, secondDomainHttpDisabledClients.size()); |
|||
} |
|||
|
|||
@Test |
|||
public void testFindAllRegistrations() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), |
|||
OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
|
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
List<OAuth2Registration> foundRegistrations = oAuth2Service.findAllRegistrations(); |
|||
Assert.assertEquals(6, foundRegistrations.size()); |
|||
oAuth2Info.getOauth2ParamsInfos().stream() |
|||
.flatMap(paramsInfo -> paramsInfo.getClientRegistrations().stream()) |
|||
.forEach(registrationInfo -> |
|||
Assert.assertTrue( |
|||
foundRegistrations.stream() |
|||
.anyMatch(registration -> registration.getClientId().equals(registrationInfo.getClientId())) |
|||
) |
|||
); |
|||
} |
|||
|
|||
@Test |
|||
public void testFindRegistrationById() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), |
|||
OAuth2DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
|
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
List<OAuth2Registration> foundRegistrations = oAuth2Service.findAllRegistrations(); |
|||
foundRegistrations.forEach(registration -> { |
|||
OAuth2Registration foundRegistration = oAuth2Service.findRegistration(registration.getUuidId()); |
|||
Assert.assertEquals(registration, foundRegistration); |
|||
}); |
|||
} |
|||
|
|||
@Test |
|||
public void testFindAppSecret() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Lists.newArrayList( |
|||
validMobileInfo("com.test.pkg1", "testPkg1AppSecret"), |
|||
validMobileInfo("com.test.pkg2", "testPkg2AppSecret") |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
|
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null); |
|||
Assert.assertEquals(3, firstDomainHttpClients.size()); |
|||
for (OAuth2ClientInfo clientInfo : firstDomainHttpClients) { |
|||
String[] segments = clientInfo.getUrl().split("/"); |
|||
String registrationId = segments[segments.length-1]; |
|||
String appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg1"); |
|||
Assert.assertNotNull(appSecret); |
|||
Assert.assertEquals("testPkg1AppSecret", appSecret); |
|||
appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg2"); |
|||
Assert.assertNotNull(appSecret); |
|||
Assert.assertEquals("testPkg2AppSecret", appSecret); |
|||
appSecret = oAuth2Service.findAppSecret(UUID.fromString(registrationId), "com.test.pkg3"); |
|||
Assert.assertNull(appSecret); |
|||
} |
|||
} |
|||
|
|||
@Test |
|||
public void testFindClientsByPackageAndPlatform() { |
|||
OAuth2Info oAuth2Info = new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Lists.newArrayList( |
|||
validMobileInfo("com.test.pkg1", "testPkg1Callback"), |
|||
validMobileInfo("com.test.pkg2", "testPkg2Callback") |
|||
)) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo("Google", Arrays.asList(PlatformType.WEB, PlatformType.ANDROID)), |
|||
validRegistrationInfo("Facebook", Arrays.asList(PlatformType.IOS)), |
|||
validRegistrationInfo("GitHub", Collections.emptyList()) |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
oAuth2Service.saveOAuth2Info(oAuth2Info); |
|||
|
|||
OAuth2Info foundOAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
Assert.assertEquals(oAuth2Info, foundOAuth2Info); |
|||
|
|||
List<OAuth2ClientInfo> firstDomainHttpClients = oAuth2Service.getOAuth2Clients("http", "first-domain", null, null); |
|||
Assert.assertEquals(3, firstDomainHttpClients.size()); |
|||
List<OAuth2ClientInfo> pkg1Clients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", null); |
|||
Assert.assertEquals(3, pkg1Clients.size()); |
|||
List<OAuth2ClientInfo> pkg1AndroidClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.ANDROID); |
|||
Assert.assertEquals(2, pkg1AndroidClients.size()); |
|||
Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("Google"))); |
|||
Assert.assertTrue(pkg1AndroidClients.stream().anyMatch(client -> client.getName().equals("GitHub"))); |
|||
List<OAuth2ClientInfo> pkg1IOSClients = oAuth2Service.getOAuth2Clients("http", "first-domain", "com.test.pkg1", PlatformType.IOS); |
|||
Assert.assertEquals(2, pkg1IOSClients.size()); |
|||
Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("Facebook"))); |
|||
Assert.assertTrue(pkg1IOSClients.stream().anyMatch(client -> client.getName().equals("GitHub"))); |
|||
} |
|||
|
|||
private OAuth2Info createDefaultOAuth2Info() { |
|||
return new OAuth2Info(true, false, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build(), |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), |
|||
OAuth2DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo(), |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
} |
|||
|
|||
private OAuth2RegistrationInfo validRegistrationInfo() { |
|||
return validRegistrationInfo(null, Collections.emptyList()); |
|||
} |
|||
|
|||
private OAuth2RegistrationInfo validRegistrationInfo(String label, List<PlatformType> platforms) { |
|||
return OAuth2RegistrationInfo.builder() |
|||
.clientId(UUID.randomUUID().toString()) |
|||
.clientSecret(UUID.randomUUID().toString()) |
|||
.authorizationUri(UUID.randomUUID().toString()) |
|||
.accessTokenUri(UUID.randomUUID().toString()) |
|||
.scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString())) |
|||
.platforms(platforms == null ? Collections.emptyList() : platforms) |
|||
.userInfoUri(UUID.randomUUID().toString()) |
|||
.userNameAttributeName(UUID.randomUUID().toString()) |
|||
.jwkSetUri(UUID.randomUUID().toString()) |
|||
.clientAuthenticationMethod(UUID.randomUUID().toString()) |
|||
.loginButtonLabel(label != null ? label : UUID.randomUUID().toString()) |
|||
.loginButtonIcon(UUID.randomUUID().toString()) |
|||
.additionalInfo(JacksonUtil.newObjectNode().put(UUID.randomUUID().toString(), UUID.randomUUID().toString())) |
|||
.mapperConfig( |
|||
OAuth2MapperConfig.builder() |
|||
.allowUserCreation(true) |
|||
.activateUser(true) |
|||
.type(MapperType.CUSTOM) |
|||
.custom( |
|||
OAuth2CustomMapperConfig.builder() |
|||
.url(UUID.randomUUID().toString()) |
|||
.build() |
|||
) |
|||
.build() |
|||
) |
|||
.build(); |
|||
} |
|||
|
|||
private OAuth2MobileInfo validMobileInfo(String pkgName, String appSecret) { |
|||
return OAuth2MobileInfo.builder().pkgName(pkgName) |
|||
.appSecret(appSecret != null ? appSecret : StringUtils.randomAlphanumeric(24)) |
|||
.build(); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue