committed by
GitHub
173 changed files with 6974 additions and 3810 deletions
@ -0,0 +1,132 @@ |
|||||
|
/** |
||||
|
* 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 jakarta.validation.Valid; |
||||
|
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.PutMapping; |
||||
|
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.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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_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" + SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@PostMapping(value = "/domain") |
||||
|
public Domain saveDomain( |
||||
|
@Parameter(description = "A JSON value representing the Domain.", required = true) |
||||
|
@RequestBody @Valid Domain domain, |
||||
|
@Parameter(description = "A list of oauth2 client registration ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string"))) |
||||
|
@RequestParam(name = "oauth2ClientIds", required = false) UUID[] ids) throws Exception { |
||||
|
domain.setTenantId(getTenantId()); |
||||
|
checkEntity(domain.getId(), domain, Resource.DOMAIN); |
||||
|
return tbDomainService.save(domain, getOAuth2ClientIds(ids), getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)", |
||||
|
notes = "Update oauth2 clients for the specified domain. ") |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@PutMapping(value = "/domain/{id}/oauth2Clients") |
||||
|
public void updateOauth2Clients(@PathVariable UUID id, |
||||
|
@RequestBody UUID[] clientIds) throws ThingsboardException { |
||||
|
DomainId domainId = new DomainId(id); |
||||
|
Domain domain = checkDomainId(domainId, Operation.WRITE); |
||||
|
List<OAuth2ClientId> oAuth2ClientIds = getOAuth2ClientIds(clientIds); |
||||
|
tbDomainService.updateOauth2Clients(domain, oAuth2ClientIds, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get Domain infos (getTenantDomainInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@GetMapping(value = "/domain/infos") |
||||
|
public PageData<DomainInfo> getTenantDomainInfos(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) |
||||
|
@RequestParam int pageSize, |
||||
|
@Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) |
||||
|
@RequestParam int page, |
||||
|
@Parameter(description = "Case-insensitive 'substring' filter based on domain's name") |
||||
|
@RequestParam(required = false) String textSearch, |
||||
|
@Parameter(description = SORT_PROPERTY_DESCRIPTION) |
||||
|
@RequestParam(required = false) String sortProperty, |
||||
|
@Parameter(description = SORT_ORDER_DESCRIPTION) |
||||
|
@RequestParam(required = false) String sortOrder) throws ThingsboardException { |
||||
|
accessControlService.checkPermission(getCurrentUser(), Resource.DOMAIN, Operation.READ); |
||||
|
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
||||
|
return domainService.findDomainInfosByTenantId(getTenantId(), pageLink); |
||||
|
} |
||||
|
|
||||
|
@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 domain Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAuthority('SYS_ADMIN')") |
||||
|
@DeleteMapping(value = "/domain/{id}") |
||||
|
public void deleteDomain(@PathVariable UUID id) throws Exception { |
||||
|
DomainId domainId = new DomainId(id); |
||||
|
Domain domain = checkDomainId(domainId, Operation.DELETE); |
||||
|
tbDomainService.delete(domain, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,133 @@ |
|||||
|
/** |
||||
|
* 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 jakarta.validation.Valid; |
||||
|
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.PutMapping; |
||||
|
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.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.MobileAppId; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
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.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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 org.thingsboard.server.service.security.permission.Resource; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_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 mobile app. " + |
||||
|
"Referencing non-existing Mobile App Id will cause 'Not Found' error." + |
||||
|
"\n\nMobile app package name is unique for entire platform setup.\n\n" + SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@PostMapping(value = "/mobileApp") |
||||
|
public MobileApp saveMobileApp( |
||||
|
@Parameter(description = "A JSON value representing the Mobile Application.", required = true) |
||||
|
@RequestBody @Valid MobileApp mobileApp, |
||||
|
@Parameter(description = "A list of entity oauth2 client ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string"))) |
||||
|
@RequestParam(name = "oauth2ClientIds", required = false) UUID[] ids) throws Exception { |
||||
|
mobileApp.setTenantId(getTenantId()); |
||||
|
checkEntity(mobileApp.getId(), mobileApp, Resource.MOBILE_APP); |
||||
|
return tbMobileAppService.save(mobileApp, getOAuth2ClientIds(ids), getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)", |
||||
|
notes = "Update oauth2 clients of the specified mobile app. ") |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@PutMapping(value = "/mobileApp/{id}/oauth2Clients") |
||||
|
public void updateOauth2Clients(@PathVariable UUID id, |
||||
|
@RequestBody UUID[] clientIds) throws ThingsboardException { |
||||
|
MobileAppId mobileAppId = new MobileAppId(id); |
||||
|
MobileApp mobileApp = checkMobileAppId(mobileAppId, Operation.WRITE); |
||||
|
List<OAuth2ClientId> oAuth2ClientIds = getOAuth2ClientIds(clientIds); |
||||
|
tbMobileAppService.updateOauth2Clients(mobileApp, oAuth2ClientIds, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get mobile app infos (getTenantMobileAppInfos)", notes = SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')") |
||||
|
@GetMapping(value = "/mobileApp/infos") |
||||
|
public PageData<MobileAppInfo> getTenantMobileAppInfos(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) |
||||
|
@RequestParam int pageSize, |
||||
|
@Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) |
||||
|
@RequestParam int page, |
||||
|
@Parameter(description = "Case-insensitive 'substring' filter based on app's name") |
||||
|
@RequestParam(required = false) String textSearch, |
||||
|
@Parameter(description = SORT_PROPERTY_DESCRIPTION) |
||||
|
@RequestParam(required = false) String sortProperty, |
||||
|
@Parameter(description = SORT_ORDER_DESCRIPTION) |
||||
|
@RequestParam(required = false) String sortOrder) throws ThingsboardException { |
||||
|
accessControlService.checkPermission(getCurrentUser(), Resource.MOBILE_APP, Operation.READ); |
||||
|
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
||||
|
return mobileAppService.findMobileAppInfosByTenantId(getTenantId(), pageLink); |
||||
|
} |
||||
|
|
||||
|
@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 mobile app Id will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) |
||||
|
@PreAuthorize("hasAuthority('SYS_ADMIN')") |
||||
|
@DeleteMapping(value = "/mobileApp/{id}") |
||||
|
public void deleteMobileApp(@PathVariable UUID id) throws Exception { |
||||
|
MobileAppId mobileAppId = new MobileAppId(id); |
||||
|
MobileApp mobileApp = checkMobileAppId(mobileAppId, Operation.DELETE); |
||||
|
tbMobileAppService.delete(mobileApp, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,84 @@ |
|||||
|
/** |
||||
|
* 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.apache.commons.collections4.CollectionUtils; |
||||
|
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.domain.Domain; |
||||
|
import org.thingsboard.server.common.data.id.DomainId; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
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; |
||||
|
|
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class DefaultTbDomainService extends AbstractTbEntityService implements TbDomainService { |
||||
|
|
||||
|
private final DomainService domainService; |
||||
|
|
||||
|
@Override |
||||
|
public Domain save(Domain domain, List<OAuth2ClientId> 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)); |
||||
|
if (CollectionUtils.isNotEmpty(oAuth2Clients)) { |
||||
|
domainService.updateOauth2Clients(domain.getTenantId(), savedDomain.getId(), oAuth2Clients); |
||||
|
} |
||||
|
logEntityActionService.logEntityAction(tenantId, savedDomain.getId(), savedDomain, actionType, user, oAuth2Clients); |
||||
|
return savedDomain; |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DOMAIN), domain, actionType, user, e, oAuth2Clients); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateOauth2Clients(Domain domain, List<OAuth2ClientId> oAuth2ClientIds, User user) { |
||||
|
ActionType actionType = ActionType.UPDATED; |
||||
|
TenantId tenantId = domain.getTenantId(); |
||||
|
DomainId domainId = domain.getId(); |
||||
|
try { |
||||
|
domainService.updateOauth2Clients(tenantId, domainId, oAuth2ClientIds); |
||||
|
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, oAuth2ClientIds); |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, e, oAuth2ClientIds); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
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); |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, domainId, domain, actionType, user, e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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.service.entitiy.domain; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.User; |
||||
|
import org.thingsboard.server.common.data.domain.Domain; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface TbDomainService { |
||||
|
|
||||
|
Domain save(Domain domain, List<OAuth2ClientId> oAuth2Clients, User user) throws Exception; |
||||
|
|
||||
|
void updateOauth2Clients(Domain domain, List<OAuth2ClientId> oAuth2ClientIds, User user); |
||||
|
|
||||
|
void delete(Domain domain, User user); |
||||
|
|
||||
|
} |
||||
@ -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.service.entitiy.mobile; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.apache.commons.collections4.CollectionUtils; |
||||
|
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.MobileAppId; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
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<OAuth2ClientId> 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)); |
||||
|
if (CollectionUtils.isNotEmpty(oauth2Clients)) { |
||||
|
mobileAppService.updateOauth2Clients(tenantId, savedMobileApp.getId(), oauth2Clients); |
||||
|
} |
||||
|
logEntityActionService.logEntityAction(tenantId, savedMobileApp.getId(), savedMobileApp, actionType, user); |
||||
|
return savedMobileApp; |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.MOBILE_APP), mobileApp, actionType, user, e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateOauth2Clients(MobileApp mobileApp, List<OAuth2ClientId> oAuth2ClientIds, User user) { |
||||
|
ActionType actionType = ActionType.UPDATED; |
||||
|
TenantId tenantId = mobileApp.getTenantId(); |
||||
|
MobileAppId mobileAppId = mobileApp.getId(); |
||||
|
try { |
||||
|
mobileAppService.updateOauth2Clients(tenantId, mobileAppId, oAuth2ClientIds); |
||||
|
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, oAuth2ClientIds); |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, e, oAuth2ClientIds); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
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); |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, mobileAppId, mobileApp, actionType, user, e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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.service.entitiy.mobile; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.User; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.mobile.MobileApp; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface TbMobileAppService { |
||||
|
|
||||
|
MobileApp save(MobileApp mobileApp, List<OAuth2ClientId> oauth2Clients, User user) throws Exception; |
||||
|
|
||||
|
void updateOauth2Clients(MobileApp mobileApp, List<OAuth2ClientId> oAuth2ClientIds, User user); |
||||
|
|
||||
|
void delete(MobileApp mobileApp, User user); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
/** |
||||
|
* 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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
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 OAuth2Client save(OAuth2Client oAuth2Client, User user) throws Exception { |
||||
|
ActionType actionType = oAuth2Client.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
TenantId tenantId = oAuth2Client.getTenantId(); |
||||
|
try { |
||||
|
OAuth2Client savedClient = checkNotNull(oAuth2ClientService.saveOAuth2Client(tenantId, oAuth2Client)); |
||||
|
logEntityActionService.logEntityAction(tenantId, savedClient.getId(), savedClient, actionType, user); |
||||
|
return savedClient; |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OAUTH2_CLIENT), oAuth2Client, actionType, user, e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void delete(OAuth2Client oAuth2Client, User user) { |
||||
|
ActionType actionType = ActionType.DELETED; |
||||
|
TenantId tenantId = oAuth2Client.getTenantId(); |
||||
|
OAuth2ClientId oAuth2ClientId = oAuth2Client.getId(); |
||||
|
try { |
||||
|
oAuth2ClientService.deleteOAuth2ClientById(tenantId, oAuth2ClientId); |
||||
|
logEntityActionService.logEntityAction(tenantId, oAuth2ClientId, oAuth2Client, actionType, user); |
||||
|
} catch (Exception e) { |
||||
|
logEntityActionService.logEntityAction(tenantId, oAuth2ClientId, oAuth2Client, actionType, user, e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,139 @@ |
|||||
|
/** |
||||
|
* 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 com.fasterxml.jackson.core.type.TypeReference; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.junit.After; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Test; |
||||
|
import org.thingsboard.server.common.data.domain.Domain; |
||||
|
import org.thingsboard.server.common.data.domain.DomainInfo; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
|
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
import static org.hamcrest.Matchers.containsString; |
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
|
||||
|
@Slf4j |
||||
|
@DaoSqlTest |
||||
|
public class DomainControllerTest extends AbstractControllerTest { |
||||
|
|
||||
|
static final TypeReference<PageData<DomainInfo>> PAGE_DATA_DOMAIN_TYPE_REF = new TypeReference<>() { |
||||
|
}; |
||||
|
static final TypeReference<PageData<OAuth2ClientInfo>> PAGE_DATA_OAUTH2_CLIENT_TYPE_REF = new TypeReference<>() { |
||||
|
}; |
||||
|
|
||||
|
@Before |
||||
|
public void setUp() throws Exception { |
||||
|
loginSysAdmin(); |
||||
|
} |
||||
|
|
||||
|
@After |
||||
|
public void tearDown() throws Exception { |
||||
|
PageData<DomainInfo> pageData = doGetTypedWithPageLink("/api/domain/infos?", PAGE_DATA_DOMAIN_TYPE_REF, new PageLink(10, 0)); |
||||
|
for (Domain domain : pageData.getData()) { |
||||
|
doDelete("/api/domain/" + domain.getId().getId()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
|
||||
|
PageData<OAuth2ClientInfo> clients = doGetTypedWithPageLink("/api/oauth2/client/infos?", PAGE_DATA_OAUTH2_CLIENT_TYPE_REF, new PageLink(10, 0)); |
||||
|
for (OAuth2ClientInfo oAuth2ClientInfo : clients.getData()) { |
||||
|
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveDomain() throws Exception { |
||||
|
PageData<DomainInfo> pageData = doGetTypedWithPageLink("/api/domain/infos?", PAGE_DATA_DOMAIN_TYPE_REF, new PageLink(10, 0)); |
||||
|
assertThat(pageData.getData()).isEmpty(); |
||||
|
|
||||
|
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true); |
||||
|
Domain savedDomain = doPost("/api/domain", domain, Domain.class); |
||||
|
|
||||
|
PageData<DomainInfo> pageData2 = doGetTypedWithPageLink("/api/domain/infos?", PAGE_DATA_DOMAIN_TYPE_REF, new PageLink(10, 0)); |
||||
|
assertThat(pageData2.getData()).hasSize(1); |
||||
|
assertThat(pageData2.getData().get(0)).isEqualTo(new DomainInfo(savedDomain, Collections.emptyList())); |
||||
|
|
||||
|
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId()); |
||||
|
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, Collections.emptyList())); |
||||
|
|
||||
|
doDelete("/api/domain/" + savedDomain.getId().getId()); |
||||
|
doGet("/api/domain/info/{id}", savedDomain.getId().getId()) |
||||
|
.andExpect(status().isNotFound()); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveDomainWithoutName() throws Exception { |
||||
|
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, null, true, true); |
||||
|
doPost("/api/domain", domain) |
||||
|
.andExpect(status().isBadRequest()) |
||||
|
.andExpect(statusReason(containsString("name must not be blank"))); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testUpdateDomainOauth2Clients() throws Exception { |
||||
|
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true); |
||||
|
Domain savedDomain = doPost("/api/domain", domain, Domain.class); |
||||
|
|
||||
|
OAuth2Client oAuth2Client = createOauth2Client(TenantId.SYS_TENANT_ID, "test google client"); |
||||
|
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); |
||||
|
|
||||
|
OAuth2Client oAuth2Client2 = createOauth2Client(TenantId.SYS_TENANT_ID, "test facebook client"); |
||||
|
OAuth2Client savedOAuth2Client2 = doPost("/api/oauth2/client", oAuth2Client2, OAuth2Client.class); |
||||
|
|
||||
|
doPut("/api/domain/" + savedDomain.getId() + "/oauth2Clients", List.of(savedOAuth2Client.getId().getId(), savedOAuth2Client2.getId().getId())); |
||||
|
|
||||
|
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId()); |
||||
|
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client), |
||||
|
new OAuth2ClientInfo(savedOAuth2Client2)))); |
||||
|
|
||||
|
doPut("/api/domain/" + savedDomain.getId() + "/oauth2Clients", List.of(savedOAuth2Client2.getId().getId())); |
||||
|
DomainInfo retrievedDomainInfo2 = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId()); |
||||
|
assertThat(retrievedDomainInfo2).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client2)))); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testCreateDomainWithOauth2Clients() throws Exception { |
||||
|
OAuth2Client oAuth2Client = createOauth2Client(TenantId.SYS_TENANT_ID, "test google client"); |
||||
|
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); |
||||
|
|
||||
|
Domain domain = constructDomain(TenantId.SYS_TENANT_ID, "my.test.domain", true, true); |
||||
|
Domain savedDomain = doPost("/api/domain?oauth2ClientIds=" + savedOAuth2Client.getId().getId(), domain, Domain.class); |
||||
|
|
||||
|
DomainInfo retrievedDomainInfo = doGet("/api/domain/info/{id}", DomainInfo.class, savedDomain.getId().getId()); |
||||
|
assertThat(retrievedDomainInfo).isEqualTo(new DomainInfo(savedDomain, List.of(new OAuth2ClientInfo(savedOAuth2Client)))); |
||||
|
} |
||||
|
|
||||
|
private Domain constructDomain(TenantId tenantId, String domainName, boolean oauth2Enabled, boolean propagateToEdge) { |
||||
|
Domain domain = new Domain(); |
||||
|
domain.setTenantId(tenantId); |
||||
|
domain.setName(domainName); |
||||
|
domain.setOauth2Enabled(oauth2Enabled); |
||||
|
domain.setPropagateToEdge(propagateToEdge); |
||||
|
return domain; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,141 @@ |
|||||
|
/** |
||||
|
* 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 com.fasterxml.jackson.core.type.TypeReference; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.junit.After; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Test; |
||||
|
import org.thingsboard.server.common.data.StringUtils; |
||||
|
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.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
|
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
import static org.hamcrest.Matchers.containsString; |
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
|
||||
|
@Slf4j |
||||
|
@DaoSqlTest |
||||
|
public class MobileAppControllerTest extends AbstractControllerTest { |
||||
|
|
||||
|
static final TypeReference<PageData<MobileAppInfo>> PAGE_DATA_MOBILE_APP_TYPE_REF = new TypeReference<>() { |
||||
|
}; |
||||
|
static final TypeReference<PageData<OAuth2ClientInfo>> PAGE_DATA_OAUTH2_CLIENT_TYPE_REF = new TypeReference<>() { |
||||
|
}; |
||||
|
|
||||
|
@Before |
||||
|
public void setUp() throws Exception { |
||||
|
loginSysAdmin(); |
||||
|
} |
||||
|
|
||||
|
@After |
||||
|
public void tearDown() throws Exception { |
||||
|
PageData<MobileAppInfo> pageData = doGetTypedWithPageLink("/api/mobileApp/infos?", PAGE_DATA_MOBILE_APP_TYPE_REF, new PageLink(10, 0)); |
||||
|
for (MobileApp mobileApp : pageData.getData()) { |
||||
|
doDelete("/api/mobileApp/" + mobileApp.getId().getId()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
|
||||
|
PageData<OAuth2ClientInfo> clients = doGetTypedWithPageLink("/api/oauth2/client/infos?", PAGE_DATA_OAUTH2_CLIENT_TYPE_REF, new PageLink(10, 0)); |
||||
|
for (OAuth2ClientInfo oAuth2ClientInfo : clients.getData()) { |
||||
|
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveMobileApp() throws Exception { |
||||
|
PageData<MobileAppInfo> pageData = doGetTypedWithPageLink("/api/mobileApp/infos?", PAGE_DATA_MOBILE_APP_TYPE_REF, new PageLink(10, 0)); |
||||
|
assertThat(pageData.getData()).isEmpty(); |
||||
|
|
||||
|
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true); |
||||
|
MobileApp savedMobileApp = doPost("/api/mobileApp", mobileApp, MobileApp.class); |
||||
|
|
||||
|
PageData<MobileAppInfo> pageData2 = doGetTypedWithPageLink("/api/mobileApp/infos?", PAGE_DATA_MOBILE_APP_TYPE_REF, new PageLink(10, 0)); |
||||
|
assertThat(pageData2.getData()).hasSize(1); |
||||
|
assertThat(pageData2.getData().get(0)).isEqualTo(new MobileAppInfo(savedMobileApp, Collections.emptyList())); |
||||
|
|
||||
|
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId()); |
||||
|
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, Collections.emptyList())); |
||||
|
|
||||
|
doDelete("/api/mobileApp/" + savedMobileApp.getId().getId()); |
||||
|
doGet("/api/mobileApp/info/{id}", savedMobileApp.getId().getId()) |
||||
|
.andExpect(status().isNotFound()); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveMobileAppWithShortAppSecret() throws Exception { |
||||
|
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "mobileApp.ce", true); |
||||
|
mobileApp.setAppSecret("short"); |
||||
|
doPost("/api/mobileApp", mobileApp) |
||||
|
.andExpect(status().isBadRequest()) |
||||
|
.andExpect(statusReason(containsString("appSecret must be at least 16 and max 2048 characters"))); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testUpdateMobileAppOauth2Clients() throws Exception { |
||||
|
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true); |
||||
|
MobileApp savedMobileApp = doPost("/api/mobileApp", mobileApp, MobileApp.class); |
||||
|
|
||||
|
OAuth2Client oAuth2Client = createOauth2Client(TenantId.SYS_TENANT_ID, "test google client"); |
||||
|
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); |
||||
|
|
||||
|
OAuth2Client oAuth2Client2 = createOauth2Client(TenantId.SYS_TENANT_ID, "test facebook client"); |
||||
|
OAuth2Client savedOAuth2Client2 = doPost("/api/oauth2/client", oAuth2Client2, OAuth2Client.class); |
||||
|
|
||||
|
doPut("/api/mobileApp/" + savedMobileApp.getId() + "/oauth2Clients", List.of(savedOAuth2Client.getId().getId(), savedOAuth2Client2.getId().getId())); |
||||
|
|
||||
|
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId()); |
||||
|
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client), |
||||
|
new OAuth2ClientInfo(savedOAuth2Client2)))); |
||||
|
|
||||
|
doPut("/api/mobileApp/" + savedMobileApp.getId() + "/oauth2Clients", List.of(savedOAuth2Client2.getId().getId())); |
||||
|
MobileAppInfo retrievedMobileAppInfo2 = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId()); |
||||
|
assertThat(retrievedMobileAppInfo2).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client2)))); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testCreateMobileAppWithOauth2Clients() throws Exception { |
||||
|
OAuth2Client oAuth2Client = createOauth2Client(TenantId.SYS_TENANT_ID, "test google client"); |
||||
|
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); |
||||
|
|
||||
|
MobileApp mobileApp = validMobileApp(TenantId.SYS_TENANT_ID, "my.test.package", true); |
||||
|
MobileApp savedMobileApp = doPost("/api/mobileApp?oauth2ClientIds=" + savedOAuth2Client.getId().getId(), mobileApp, MobileApp.class); |
||||
|
|
||||
|
MobileAppInfo retrievedMobileAppInfo = doGet("/api/mobileApp/info/{id}", MobileAppInfo.class, savedMobileApp.getId().getId()); |
||||
|
assertThat(retrievedMobileAppInfo).isEqualTo(new MobileAppInfo(savedMobileApp, List.of(new OAuth2ClientInfo(savedOAuth2Client)))); |
||||
|
} |
||||
|
|
||||
|
private MobileApp validMobileApp(TenantId tenantId, String mobileAppName, boolean oauth2Enabled) { |
||||
|
MobileApp MobileApp = new MobileApp(); |
||||
|
MobileApp.setTenantId(tenantId); |
||||
|
MobileApp.setPkgName(mobileAppName); |
||||
|
MobileApp.setAppSecret(StringUtils.randomAlphanumeric(24)); |
||||
|
MobileApp.setOauth2Enabled(oauth2Enabled); |
||||
|
return MobileApp; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,76 @@ |
|||||
|
/** |
||||
|
* 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 com.fasterxml.jackson.core.type.TypeReference; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.junit.After; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Test; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
|
||||
|
@Slf4j |
||||
|
@DaoSqlTest |
||||
|
public class Oauth2ClientControllerTest extends AbstractControllerTest { |
||||
|
|
||||
|
static final TypeReference<PageData<OAuth2ClientInfo>> PAGE_DATA_OAUTH2_CLIENT_TYPE_REF = new TypeReference<>() { |
||||
|
}; |
||||
|
|
||||
|
@Before |
||||
|
public void setUp() throws Exception { |
||||
|
loginSysAdmin(); |
||||
|
} |
||||
|
|
||||
|
@After |
||||
|
public void tearDown() throws Exception { |
||||
|
PageData<OAuth2ClientInfo> pageData = doGetTypedWithPageLink("/api/oauth2/client/infos?", PAGE_DATA_OAUTH2_CLIENT_TYPE_REF, new PageLink(10, 0)); |
||||
|
for (OAuth2ClientInfo oAuth2ClientInfo : pageData.getData()) { |
||||
|
doDelete("/api/oauth2/client/" + oAuth2ClientInfo.getId().getId().toString()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveOauth2Client() throws Exception { |
||||
|
loginSysAdmin(); |
||||
|
PageData<OAuth2ClientInfo> pageData = doGetTypedWithPageLink("/api/oauth2/client/infos?", PAGE_DATA_OAUTH2_CLIENT_TYPE_REF, new PageLink(10, 0)); |
||||
|
assertThat(pageData.getData()).isEmpty(); |
||||
|
|
||||
|
OAuth2Client oAuth2Client = createOauth2Client(TenantId.SYS_TENANT_ID, "test google client"); |
||||
|
OAuth2Client savedOAuth2Client = doPost("/api/oauth2/client", oAuth2Client, OAuth2Client.class); |
||||
|
|
||||
|
PageData<OAuth2ClientInfo> pageData2 = doGetTypedWithPageLink("/api/oauth2/client/infos?", PAGE_DATA_OAUTH2_CLIENT_TYPE_REF, new PageLink(10, 0)); |
||||
|
|
||||
|
assertThat(pageData2.getData()).hasSize(1); |
||||
|
assertThat(pageData2.getData().get(0)).isEqualTo(new OAuth2ClientInfo(savedOAuth2Client)); |
||||
|
|
||||
|
OAuth2Client retrievedOAuth2ClientInfo = doGet("/api/oauth2/client/{id}", OAuth2Client.class, savedOAuth2Client.getId().getId()); |
||||
|
assertThat(retrievedOAuth2ClientInfo).isEqualTo(savedOAuth2Client); |
||||
|
|
||||
|
doDelete("/api/oauth2/client/" + savedOAuth2Client.getId().getId()); |
||||
|
doGet("/api/oauth2/client/{id}", savedOAuth2Client.getId().getId()) |
||||
|
.andExpect(status().isNotFound()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
/** |
||||
|
* 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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.entity.EntityDaoService; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface DomainService extends EntityDaoService { |
||||
|
|
||||
|
Domain saveDomain(TenantId tenantId, Domain domain); |
||||
|
|
||||
|
void deleteDomainById(TenantId tenantId, DomainId domainId); |
||||
|
|
||||
|
Domain findDomainById(TenantId tenantId, DomainId domainId); |
||||
|
|
||||
|
PageData<DomainInfo> findDomainInfosByTenantId(TenantId tenantId, PageLink pageLink); |
||||
|
|
||||
|
DomainInfo findDomainInfoById(TenantId tenantId, DomainId domainId); |
||||
|
|
||||
|
boolean isOauth2Enabled(TenantId tenantId); |
||||
|
|
||||
|
void updateOauth2Clients(TenantId tenantId, DomainId domainId, List<OAuth2ClientId> oAuth2ClientIds); |
||||
|
|
||||
|
void deleteDomainsByTenantId(TenantId tenantId); |
||||
|
} |
||||
@ -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.mobile; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.id.MobileAppId; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
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.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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); |
||||
|
|
||||
|
PageData<MobileAppInfo> findMobileAppInfosByTenantId(TenantId tenantId, PageLink pageLink); |
||||
|
|
||||
|
MobileAppInfo findMobileAppInfoById(TenantId tenantId, MobileAppId mobileAppId); |
||||
|
|
||||
|
void updateOauth2Clients(TenantId tenantId, MobileAppId mobileAppId, List<OAuth2ClientId> oAuth2ClientIds); |
||||
|
|
||||
|
void deleteMobileAppsByTenantId(TenantId tenantId); |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
/** |
||||
|
* 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 org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo; |
||||
|
import org.thingsboard.server.common.data.oauth2.PlatformType; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.entity.EntityDaoService; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
public interface OAuth2ClientService extends EntityDaoService { |
||||
|
|
||||
|
List<OAuth2ClientLoginInfo> findOAuth2ClientLoginInfosByDomainName(String domainName); |
||||
|
|
||||
|
List<OAuth2ClientLoginInfo> findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType(String pkgName, PlatformType platformType); |
||||
|
|
||||
|
List<OAuth2Client> findOAuth2ClientsByTenantId(TenantId tenantId); |
||||
|
|
||||
|
OAuth2Client saveOAuth2Client(TenantId tenantId, OAuth2Client oAuth2Client); |
||||
|
|
||||
|
OAuth2Client findOAuth2ClientById(TenantId tenantId, OAuth2ClientId providerId); |
||||
|
|
||||
|
String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName); |
||||
|
|
||||
|
void deleteOAuth2ClientById(TenantId tenantId, OAuth2ClientId oAuth2ClientId); |
||||
|
|
||||
|
void deleteOauth2ClientsByTenantId(TenantId tenantId); |
||||
|
|
||||
|
PageData<OAuth2ClientInfo> findOAuth2ClientInfosByTenantId(TenantId tenantId, PageLink pageLink); |
||||
|
|
||||
|
List<OAuth2ClientInfo> findOAuth2ClientInfosByIds(TenantId tenantId, List<OAuth2ClientId> oAuth2ClientIds); |
||||
|
|
||||
|
boolean isPropagateOAuth2ClientToEdge(TenantId tenantId, OAuth2ClientId oAuth2ClientId); |
||||
|
|
||||
|
} |
||||
@ -1,39 +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 org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
|
||||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|
||||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|
||||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
public interface OAuth2Service { |
|
||||
|
|
||||
List<OAuth2ClientInfo> getOAuth2Clients(String domainScheme, String domainName, String pkgName, PlatformType platformType); |
|
||||
|
|
||||
void saveOAuth2Info(OAuth2Info oauth2Info); |
|
||||
|
|
||||
OAuth2Info findOAuth2Info(); |
|
||||
|
|
||||
OAuth2Registration findRegistration(UUID id); |
|
||||
|
|
||||
List<OAuth2Registration> findAllRegistrations(); |
|
||||
|
|
||||
String findAppSecret(UUID registrationId, String pkgName); |
|
||||
} |
|
||||
@ -0,0 +1,62 @@ |
|||||
|
/** |
||||
|
* 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 jakarta.validation.constraints.NotBlank; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
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; |
||||
|
import org.thingsboard.server.common.data.validation.Length; |
||||
|
|
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@Data |
||||
|
@ToString |
||||
|
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) |
||||
|
@NotBlank |
||||
|
@Length(fieldName = "name") |
||||
|
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() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public Domain(DomainId id) { |
||||
|
super(id); |
||||
|
} |
||||
|
|
||||
|
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,72 @@ |
|||||
|
/** |
||||
|
* 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 jakarta.validation.constraints.NotBlank; |
||||
|
import jakarta.validation.constraints.NotEmpty; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
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; |
||||
|
import org.thingsboard.server.common.data.validation.Length; |
||||
|
|
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@Data |
||||
|
@ToString |
||||
|
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) |
||||
|
@NotBlank |
||||
|
@Length(fieldName = "pkgName") |
||||
|
private String pkgName; |
||||
|
@Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) |
||||
|
@NotEmpty |
||||
|
@Length(fieldName = "appSecret", min = 16, max = 2048, message = "must be at least 16 and max 2048 characters") |
||||
|
private String appSecret; |
||||
|
@Schema(description = "Whether OAuth2 settings are enabled or not") |
||||
|
private boolean oauth2Enabled; |
||||
|
|
||||
|
public MobileApp() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public MobileApp(MobileAppId id) { |
||||
|
super(id); |
||||
|
} |
||||
|
|
||||
|
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,47 @@ |
|||||
|
/** |
||||
|
* 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 io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import org.thingsboard.server.common.data.id.MobileAppId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@Data |
||||
|
@Schema |
||||
|
public class MobileAppInfo extends MobileApp { |
||||
|
|
||||
|
@Schema(description = "List of available oauth2 clients") |
||||
|
private List<OAuth2ClientInfo> oauth2ClientInfos; |
||||
|
|
||||
|
public MobileAppInfo(MobileApp mobileApp, List<OAuth2ClientInfo> oauth2ClientInfos) { |
||||
|
super(mobileApp); |
||||
|
this.oauth2ClientInfos = oauth2ClientInfos; |
||||
|
} |
||||
|
|
||||
|
public MobileAppInfo() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public MobileAppInfo(MobileAppId mobileAppId) { |
||||
|
super(mobileAppId); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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.OAuth2ClientId; |
||||
|
|
||||
|
@Data |
||||
|
@NoArgsConstructor |
||||
|
@AllArgsConstructor |
||||
|
public class MobileAppOauth2Client { |
||||
|
|
||||
|
private MobileAppId mobileAppId; |
||||
|
private OAuth2ClientId oAuth2ClientId; |
||||
|
|
||||
|
} |
||||
@ -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,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; |
|
||||
|
|
||||
} |
|
||||
@ -1,74 +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 com.fasterxml.jackson.annotation.JsonProperty; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
import lombok.NoArgsConstructor; |
|
||||
import lombok.ToString; |
|
||||
import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; |
|
||||
import org.thingsboard.server.common.data.HasName; |
|
||||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|
||||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@Data |
|
||||
@ToString(exclude = {"clientSecret"}) |
|
||||
@NoArgsConstructor |
|
||||
public class OAuth2Registration extends BaseDataWithAdditionalInfo<OAuth2RegistrationId> implements HasName { |
|
||||
|
|
||||
private OAuth2ParamsId oauth2ParamsId; |
|
||||
private OAuth2MapperConfig mapperConfig; |
|
||||
private String clientId; |
|
||||
private String clientSecret; |
|
||||
private String authorizationUri; |
|
||||
private String accessTokenUri; |
|
||||
private List<String> scope; |
|
||||
private String userInfoUri; |
|
||||
private String userNameAttributeName; |
|
||||
private String jwkSetUri; |
|
||||
private String clientAuthenticationMethod; |
|
||||
private String loginButtonLabel; |
|
||||
private String loginButtonIcon; |
|
||||
private List<PlatformType> platforms; |
|
||||
|
|
||||
public OAuth2Registration(OAuth2Registration registration) { |
|
||||
super(registration); |
|
||||
this.oauth2ParamsId = registration.oauth2ParamsId; |
|
||||
this.mapperConfig = registration.mapperConfig; |
|
||||
this.clientId = registration.clientId; |
|
||||
this.clientSecret = registration.clientSecret; |
|
||||
this.authorizationUri = registration.authorizationUri; |
|
||||
this.accessTokenUri = registration.accessTokenUri; |
|
||||
this.scope = registration.scope; |
|
||||
this.userInfoUri = registration.userInfoUri; |
|
||||
this.userNameAttributeName = registration.userNameAttributeName; |
|
||||
this.jwkSetUri = registration.jwkSetUri; |
|
||||
this.clientAuthenticationMethod = registration.clientAuthenticationMethod; |
|
||||
this.loginButtonLabel = registration.loginButtonLabel; |
|
||||
this.loginButtonIcon = registration.loginButtonIcon; |
|
||||
this.platforms = registration.platforms; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
|
||||
public String getName() { |
|
||||
return loginButtonLabel; |
|
||||
} |
|
||||
} |
|
||||
@ -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.domain; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.domain.Domain; |
||||
|
import org.thingsboard.server.common.data.domain.DomainOauth2Client; |
||||
|
import org.thingsboard.server.common.data.id.DomainId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.Dao; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface DomainDao extends Dao<Domain> { |
||||
|
|
||||
|
PageData<Domain> findByTenantId(TenantId tenantId, PageLink pageLink); |
||||
|
|
||||
|
int countDomainByTenantIdAndOauth2Enabled(TenantId tenantId, boolean oauth2Enabled); |
||||
|
|
||||
|
List<DomainOauth2Client> findOauth2ClientsByDomainId(TenantId tenantId, DomainId domainId); |
||||
|
|
||||
|
void addOauth2Client(DomainOauth2Client domainOauth2Client); |
||||
|
|
||||
|
void removeOauth2Client(DomainOauth2Client domainOauth2Client); |
||||
|
|
||||
|
void deleteByTenantId(TenantId tenantId); |
||||
|
} |
||||
@ -0,0 +1,160 @@ |
|||||
|
/** |
||||
|
* 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.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
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.DomainOauth2Client; |
||||
|
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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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.oauth2.OAuth2ClientDao; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Optional; |
||||
|
import java.util.Set; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class DomainServiceImpl extends AbstractEntityService implements DomainService { |
||||
|
|
||||
|
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
||||
|
|
||||
|
@Autowired |
||||
|
private OAuth2ClientDao oauth2ClientDao; |
||||
|
@Autowired |
||||
|
private DomainDao domainDao; |
||||
|
|
||||
|
@Override |
||||
|
public Domain saveDomain(TenantId tenantId, Domain domain) { |
||||
|
log.trace("Executing saveDomain [{}]", domain); |
||||
|
try { |
||||
|
Domain savedDomain = domainDao.save(tenantId, domain); |
||||
|
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedDomain.getId()).entity(savedDomain).build()); |
||||
|
return savedDomain; |
||||
|
} catch (Exception e) { |
||||
|
checkConstraintViolation(e, |
||||
|
Map.of("domain_unq_key", "Domain with such name and scheme already exists!")); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateOauth2Clients(TenantId tenantId, DomainId domainId, List<OAuth2ClientId> oAuth2ClientIds) { |
||||
|
log.trace("Executing updateOauth2Clients, domainId [{}], oAuth2ClientIds [{}]", domainId, oAuth2ClientIds); |
||||
|
Set<DomainOauth2Client> newClientList = oAuth2ClientIds.stream() |
||||
|
.map(clientId -> new DomainOauth2Client(domainId, clientId)) |
||||
|
.collect(Collectors.toSet()); |
||||
|
|
||||
|
List<DomainOauth2Client> existingClients = domainDao.findOauth2ClientsByDomainId(tenantId, domainId); |
||||
|
List<DomainOauth2Client> toRemoveList = existingClients.stream() |
||||
|
.filter(client -> !newClientList.contains(client)) |
||||
|
.toList(); |
||||
|
newClientList.removeIf(existingClients::contains); |
||||
|
|
||||
|
for (DomainOauth2Client client : toRemoveList) { |
||||
|
domainDao.removeOauth2Client(client); |
||||
|
} |
||||
|
for (DomainOauth2Client client : newClientList) { |
||||
|
domainDao.addOauth2Client(client); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteDomainById(TenantId tenantId, DomainId domainId) { |
||||
|
log.trace("Executing deleteDomainById [{}]", 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 PageData<DomainInfo> findDomainInfosByTenantId(TenantId tenantId, PageLink pageLink) { |
||||
|
log.trace("Executing findDomainInfosByTenantId [{}]", tenantId); |
||||
|
PageData<Domain> domains = domainDao.findByTenantId(tenantId, pageLink); |
||||
|
return domains.mapData(this::getDomainInfo); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public DomainInfo findDomainInfoById(TenantId tenantId, DomainId domainId) { |
||||
|
log.trace("Executing findDomainInfoById [{}] [{}]", tenantId, domainId); |
||||
|
Domain domain = domainDao.findById(tenantId, domainId.getId()); |
||||
|
return getDomainInfo(domain); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isOauth2Enabled(TenantId tenantId) { |
||||
|
log.trace("Executing isOauth2Enabled [{}] ", tenantId); |
||||
|
return domainDao.countDomainByTenantIdAndOauth2Enabled(tenantId, true) > 0; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteDomainsByTenantId(TenantId tenantId) { |
||||
|
log.trace("Executing deleteDomainsByTenantId, tenantId [{}]", tenantId); |
||||
|
domainDao.deleteByTenantId(tenantId); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteByTenantId(TenantId tenantId) { |
||||
|
deleteDomainsByTenantId(tenantId); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) { |
||||
|
return Optional.ofNullable(findDomainById(tenantId, new DomainId(entityId.getId()))); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional |
||||
|
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
||||
|
deleteDomainById(tenantId, (DomainId) id); |
||||
|
} |
||||
|
|
||||
|
private DomainInfo getDomainInfo(Domain domain) { |
||||
|
if (domain == null) { |
||||
|
return null; |
||||
|
} |
||||
|
List<OAuth2ClientInfo> clients = oauth2ClientDao.findByDomainId(domain.getUuidId()).stream() |
||||
|
.map(OAuth2ClientInfo::new) |
||||
|
.collect(Collectors.toList()); |
||||
|
return new DomainInfo(domain, clients); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public EntityType getEntityType() { |
||||
|
return EntityType.DOMAIN; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
/** |
||||
|
* 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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.mobile.MobileApp; |
||||
|
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Client; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.Dao; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface MobileAppDao extends Dao<MobileApp> { |
||||
|
|
||||
|
PageData<MobileApp> findByTenantId(TenantId tenantId, PageLink pageLink); |
||||
|
|
||||
|
List<MobileAppOauth2Client> findOauth2ClientsByMobileAppId(TenantId tenantId, MobileAppId mobileAppId); |
||||
|
|
||||
|
void addOauth2Client(MobileAppOauth2Client mobileAppOauth2Client); |
||||
|
|
||||
|
void removeOauth2Client(MobileAppOauth2Client mobileAppOauth2Client); |
||||
|
|
||||
|
void deleteByTenantId(TenantId tenantId); |
||||
|
} |
||||
@ -0,0 +1,154 @@ |
|||||
|
/** |
||||
|
* 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.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
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.OAuth2ClientId; |
||||
|
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.MobileAppOauth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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.oauth2.OAuth2ClientDao; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Optional; |
||||
|
import java.util.Set; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class MobileAppServiceImpl extends AbstractEntityService implements MobileAppService { |
||||
|
|
||||
|
@Autowired |
||||
|
private OAuth2ClientDao oauth2ClientDao; |
||||
|
@Autowired |
||||
|
private MobileAppDao mobileAppDao; |
||||
|
|
||||
|
@Override |
||||
|
public MobileApp saveMobileApp(TenantId tenantId, MobileApp mobileApp) { |
||||
|
log.trace("Executing saveMobileApp [{}]", mobileApp); |
||||
|
try { |
||||
|
MobileApp savedMobileApp = mobileAppDao.save(tenantId, mobileApp); |
||||
|
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedMobileApp).build()); |
||||
|
return savedMobileApp; |
||||
|
} catch (Exception e) { |
||||
|
checkConstraintViolation(e, |
||||
|
Map.of("mobile_app_unq_key", "Mobile app with such package already exists!")); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@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 PageData<MobileAppInfo> findMobileAppInfosByTenantId(TenantId tenantId, PageLink pageLink) { |
||||
|
log.trace("Executing findMobileAppInfosByTenantId [{}]", tenantId); |
||||
|
PageData<MobileApp> mobiles = mobileAppDao.findByTenantId(tenantId, pageLink); |
||||
|
return mobiles.mapData(this::getMobileAppInfo); |
||||
|
} |
||||
|
|
||||
|
@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 getMobileAppInfo(mobileApp); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateOauth2Clients(TenantId tenantId, MobileAppId mobileAppId, List<OAuth2ClientId> oAuth2ClientIds) { |
||||
|
log.trace("Executing updateOauth2Clients, mobileAppId [{}], oAuth2ClientIds [{}]", mobileAppId, oAuth2ClientIds); |
||||
|
Set<MobileAppOauth2Client> newClientList = oAuth2ClientIds.stream() |
||||
|
.map(clientId -> new MobileAppOauth2Client(mobileAppId, clientId)) |
||||
|
.collect(Collectors.toSet()); |
||||
|
|
||||
|
List<MobileAppOauth2Client> existingClients = mobileAppDao.findOauth2ClientsByMobileAppId(tenantId, mobileAppId); |
||||
|
List<MobileAppOauth2Client> toRemoveList = existingClients.stream() |
||||
|
.filter(client -> !newClientList.contains(client)) |
||||
|
.toList(); |
||||
|
newClientList.removeIf(existingClients::contains); |
||||
|
|
||||
|
for (MobileAppOauth2Client client : toRemoveList) { |
||||
|
mobileAppDao.removeOauth2Client(client); |
||||
|
} |
||||
|
for (MobileAppOauth2Client client : newClientList) { |
||||
|
mobileAppDao.addOauth2Client(client); |
||||
|
} |
||||
|
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 |
||||
|
@Transactional |
||||
|
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
||||
|
deleteMobileAppById(tenantId, (MobileAppId) id); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteMobileAppsByTenantId(TenantId tenantId) { |
||||
|
log.trace("Executing deleteMobileAppsByTenantId, tenantId [{}]", tenantId); |
||||
|
mobileAppDao.deleteByTenantId(tenantId); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteByTenantId(TenantId tenantId) { |
||||
|
deleteMobileAppsByTenantId(tenantId); |
||||
|
} |
||||
|
|
||||
|
private MobileAppInfo getMobileAppInfo(MobileApp mobileApp) { |
||||
|
List<OAuth2ClientInfo> clients = oauth2ClientDao.findByMobileAppId(mobileApp.getUuidId()).stream() |
||||
|
.map(OAuth2ClientInfo::new) |
||||
|
.collect(Collectors.toList()); |
||||
|
return new MobileAppInfo(mobileApp, clients); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public EntityType getEntityType() { |
||||
|
return EntityType.MOBILE_APP; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
/** |
||||
|
* 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_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) { |
||||
|
super(domain); |
||||
|
if (domain.getTenantId() != null) { |
||||
|
this.tenantId = domain.getTenantId().getId(); |
||||
|
} |
||||
|
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 DomainOauth2ClientCompositeKey implements Serializable { |
||||
|
|
||||
|
@Transient |
||||
|
private static final long serialVersionUID = -245388185894468455L; |
||||
|
|
||||
|
private UUID domainId; |
||||
|
private UUID oauth2ClientId; |
||||
|
|
||||
|
} |
||||
@ -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.DomainOauth2Client; |
||||
|
import org.thingsboard.server.common.data.id.DomainId; |
||||
|
import org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
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_CLIENT_DOMAIN_ID_PROPERTY; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.DOMAIN_OAUTH2_CLIENT_TABLE_NAME; |
||||
|
|
||||
|
@Data |
||||
|
@Entity |
||||
|
@Table(name = DOMAIN_OAUTH2_CLIENT_TABLE_NAME) |
||||
|
@IdClass(DomainOauth2ClientCompositeKey.class) |
||||
|
public final class DomainOauth2ClientEntity implements ToData<DomainOauth2Client> { |
||||
|
|
||||
|
@Id |
||||
|
@Column(name = DOMAIN_OAUTH2_CLIENT_DOMAIN_ID_PROPERTY, columnDefinition = "uuid") |
||||
|
private UUID domainId; |
||||
|
|
||||
|
@Id |
||||
|
@Column(name = ModelConstants.DOMAIN_OAUTH2_CLIENT_CLIENT_ID_PROPERTY, columnDefinition = "uuid") |
||||
|
private UUID oauth2ClientId; |
||||
|
|
||||
|
|
||||
|
public DomainOauth2ClientEntity() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public DomainOauth2ClientEntity(DomainOauth2Client domainOauth2Client) { |
||||
|
domainId = domainOauth2Client.getDomainId().getId(); |
||||
|
oauth2ClientId = domainOauth2Client.getOAuth2ClientId().getId(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public DomainOauth2Client toData() { |
||||
|
DomainOauth2Client result = new DomainOauth2Client(); |
||||
|
result.setDomainId(new DomainId(domainId)); |
||||
|
result.setOAuth2ClientId(new OAuth2ClientId(oauth2ClientId)); |
||||
|
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 MobileAppOauth2ClientCompositeKey implements Serializable { |
||||
|
|
||||
|
@Transient |
||||
|
private static final long serialVersionUID = -245388185894468455L; |
||||
|
|
||||
|
private UUID mobileAppId; |
||||
|
private UUID oauth2ClientId; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
/** |
||||
|
* 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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.mobile.MobileAppOauth2Client; |
||||
|
import org.thingsboard.server.dao.model.ToData; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_CLIENT_MOBILE_APP_ID_PROPERTY; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_CLIENT_CLIENT_ID_PROPERTY; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_OAUTH2_CLIENT_TABLE_NAME; |
||||
|
|
||||
|
@Data |
||||
|
@Entity |
||||
|
@Table(name = MOBILE_APP_OAUTH2_CLIENT_TABLE_NAME) |
||||
|
@IdClass(MobileAppOauth2ClientCompositeKey.class) |
||||
|
public final class MobileAppOauth2ClientEntity implements ToData<MobileAppOauth2Client> { |
||||
|
|
||||
|
@Id |
||||
|
@Column(name = MOBILE_APP_OAUTH2_CLIENT_MOBILE_APP_ID_PROPERTY, columnDefinition = "uuid") |
||||
|
private UUID mobileAppId; |
||||
|
|
||||
|
@Id |
||||
|
@Column(name = MOBILE_APP_OAUTH2_CLIENT_CLIENT_ID_PROPERTY, columnDefinition = "uuid") |
||||
|
private UUID oauth2ClientId; |
||||
|
|
||||
|
public MobileAppOauth2ClientEntity() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public MobileAppOauth2ClientEntity(MobileAppOauth2Client domainOauth2Provider) { |
||||
|
mobileAppId = domainOauth2Provider.getMobileAppId().getId(); |
||||
|
oauth2ClientId = domainOauth2Provider.getOAuth2ClientId().getId(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public MobileAppOauth2Client toData() { |
||||
|
MobileAppOauth2Client result = new MobileAppOauth2Client(); |
||||
|
result.setMobileAppId(new MobileAppId(mobileAppId)); |
||||
|
result.setOAuth2ClientId(new OAuth2ClientId(oauth2ClientId)); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
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 OAuth2ClientInfoEntity extends BaseSqlEntity<OAuth2ClientInfo> { |
||||
|
|
||||
|
private String platforms; |
||||
|
private String title; |
||||
|
|
||||
|
public OAuth2ClientInfoEntity() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public OAuth2ClientInfoEntity(UUID id, long createdTime, String platforms, String title) { |
||||
|
this.id = id; |
||||
|
this.createdTime = createdTime; |
||||
|
this.platforms = platforms; |
||||
|
this.title = title; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OAuth2ClientInfo toData() { |
||||
|
OAuth2ClientInfo oAuth2ClientInfo = new OAuth2ClientInfo(); |
||||
|
oAuth2ClientInfo.setId(new OAuth2ClientId(id)); |
||||
|
oAuth2ClientInfo.setCreatedTime(createdTime); |
||||
|
oAuth2ClientInfo.setTitle(title); |
||||
|
oAuth2ClientInfo.setPlatforms(StringUtils.isNotEmpty(platforms) ? Arrays.stream(platforms.split(",")) |
||||
|
.map(str -> PlatformType.valueOf(str)).collect(Collectors.toList()) : Collections.emptyList()); |
||||
|
return oAuth2ClientInfo; |
||||
|
} |
||||
|
} |
||||
@ -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 jakarta.persistence.Column; |
|
||||
import jakarta.persistence.Entity; |
|
||||
import jakarta.persistence.EnumType; |
|
||||
import jakarta.persistence.Enumerated; |
|
||||
import jakarta.persistence.Table; |
|
||||
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 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 jakarta.persistence.Column; |
|
||||
import jakarta.persistence.Entity; |
|
||||
import jakarta.persistence.Table; |
|
||||
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 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,49 @@ |
|||||
|
/** |
||||
|
* 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 org.thingsboard.server.common.data.id.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.PlatformType; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.Dao; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
public interface OAuth2ClientDao extends Dao<OAuth2Client> { |
||||
|
|
||||
|
PageData<OAuth2Client> findByTenantId(UUID tenantId, PageLink pageLink); |
||||
|
|
||||
|
List<OAuth2Client> findEnabledByDomainName(String domainName); |
||||
|
|
||||
|
List<OAuth2Client> findEnabledByPkgNameAndPlatformType(String pkgName, PlatformType platformType); |
||||
|
|
||||
|
List<OAuth2Client> findByDomainId(UUID domainId); |
||||
|
|
||||
|
List<OAuth2Client> findByMobileAppId(UUID mobileAppId); |
||||
|
|
||||
|
String findAppSecret(UUID id, String pkgName); |
||||
|
|
||||
|
void deleteByTenantId(UUID tenantId); |
||||
|
|
||||
|
List<OAuth2Client> findByIds(UUID tenantId, List<OAuth2ClientId> oAuth2ClientIds); |
||||
|
|
||||
|
boolean isPropagateToEdge(TenantId tenantId, UUID oAuth2ClientId); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,159 @@ |
|||||
|
/** |
||||
|
* 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.OAuth2ClientId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; |
||||
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo; |
||||
|
import org.thingsboard.server.common.data.oauth2.PlatformType; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
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.stream.Collectors; |
||||
|
|
||||
|
|
||||
|
@Slf4j |
||||
|
@Service("OAuth2ClientService") |
||||
|
public class OAuth2ClientServiceImpl extends AbstractEntityService implements OAuth2ClientService { |
||||
|
|
||||
|
@Autowired |
||||
|
private OAuth2ClientDao oauth2ClientDao; |
||||
|
@Autowired |
||||
|
private DataValidator<OAuth2Client> oAuth2ClientDataValidator; |
||||
|
|
||||
|
@Override |
||||
|
public List<OAuth2ClientLoginInfo> findOAuth2ClientLoginInfosByDomainName(String domainName) { |
||||
|
log.trace("Executing findOAuth2ClientLoginInfosByDomainName [{}] ", domainName); |
||||
|
return oauth2ClientDao.findEnabledByDomainName(domainName) |
||||
|
.stream() |
||||
|
.map(OAuth2Utils::toClientLoginInfo) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<OAuth2ClientLoginInfo> findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType(String pkgName, PlatformType platformType) { |
||||
|
log.trace("Executing findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType pkgName=[{}] platformType=[{}]",pkgName, platformType); |
||||
|
return oauth2ClientDao.findEnabledByPkgNameAndPlatformType(pkgName, platformType) |
||||
|
.stream() |
||||
|
.map(OAuth2Utils::toClientLoginInfo) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional |
||||
|
public OAuth2Client saveOAuth2Client(TenantId tenantId, OAuth2Client oAuth2Client) { |
||||
|
log.trace("Executing saveOAuth2Client [{}]", oAuth2Client); |
||||
|
oAuth2ClientDataValidator.validate(oAuth2Client, OAuth2Client::getTenantId); |
||||
|
OAuth2Client savedOauth2Client = oauth2ClientDao.save(tenantId, oAuth2Client); |
||||
|
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedOauth2Client.getId()).entity(savedOauth2Client).build()); |
||||
|
return savedOauth2Client; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OAuth2Client findOAuth2ClientById(TenantId tenantId, OAuth2ClientId oAuth2ClientId) { |
||||
|
log.trace("Executing findOAuth2ClientById [{}]", oAuth2ClientId); |
||||
|
return oauth2ClientDao.findById(tenantId, oAuth2ClientId.getId()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<OAuth2Client> findOAuth2ClientsByTenantId(TenantId tenantId) { |
||||
|
log.trace("Executing findOAuth2ClientsByTenantId [{}]", tenantId); |
||||
|
return oauth2ClientDao.findByTenantId(tenantId.getId(), new PageLink(Integer.MAX_VALUE)).getData(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String findAppSecret(OAuth2ClientId oAuth2ClientId, String pkgName) { |
||||
|
log.trace("Executing findAppSecret oAuth2ClientId = [{}] pkgName = [{}]", oAuth2ClientId, pkgName); |
||||
|
return oauth2ClientDao.findAppSecret(oAuth2ClientId.getId(), pkgName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional |
||||
|
public void deleteOAuth2ClientById(TenantId tenantId, OAuth2ClientId oAuth2ClientId) { |
||||
|
log.trace("Executing deleteOAuth2ClientById [{}]", oAuth2ClientId); |
||||
|
oauth2ClientDao.removeById(tenantId, oAuth2ClientId.getId()); |
||||
|
eventPublisher.publishEvent(DeleteEntityEvent.builder() |
||||
|
.tenantId(tenantId) |
||||
|
.entityId(oAuth2ClientId) |
||||
|
.build()); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteOauth2ClientsByTenantId(TenantId tenantId) { |
||||
|
log.trace("Executing deleteOauth2ClientsByTenantId, tenantId [{}]", tenantId); |
||||
|
oauth2ClientDao.deleteByTenantId(tenantId.getId()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public PageData<OAuth2ClientInfo> findOAuth2ClientInfosByTenantId(TenantId tenantId, PageLink pageLink) { |
||||
|
log.trace("Executing findOAuth2ClientInfosByTenantId tenantId=[{}]", tenantId); |
||||
|
PageData<OAuth2Client> clients = oauth2ClientDao.findByTenantId(tenantId.getId(), pageLink); |
||||
|
return clients.mapData(OAuth2ClientInfo::new); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<OAuth2ClientInfo> findOAuth2ClientInfosByIds(TenantId tenantId, List<OAuth2ClientId> oAuth2ClientIds) { |
||||
|
log.trace("Executing findQueueStatsByIds, tenantId [{}], oAuth2ClientIds [{}]", tenantId, oAuth2ClientIds); |
||||
|
return oauth2ClientDao.findByIds(tenantId.getId(), oAuth2ClientIds) |
||||
|
.stream() |
||||
|
.map(OAuth2ClientInfo::new) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isPropagateOAuth2ClientToEdge(TenantId tenantId, OAuth2ClientId oAuth2ClientId) { |
||||
|
log.trace("Executing isPropagateOAuth2ClientToEdge, tenantId [{}], oAuth2ClientId [{}]", tenantId, oAuth2ClientId); |
||||
|
return oauth2ClientDao.isPropagateToEdge(tenantId, oAuth2ClientId.getId()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteByTenantId(TenantId tenantId) { |
||||
|
deleteOauth2ClientsByTenantId(tenantId); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) { |
||||
|
return Optional.ofNullable(findOAuth2ClientById(tenantId, new OAuth2ClientId(entityId.getId()))); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional |
||||
|
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) { |
||||
|
deleteOAuth2ClientById(tenantId, (OAuth2ClientId) id); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public EntityType getEntityType() { |
||||
|
return EntityType.OAUTH2_CLIENT; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -1,34 +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 org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|
||||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|
||||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|
||||
import org.thingsboard.server.dao.Dao; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
public interface OAuth2RegistrationDao extends Dao<OAuth2Registration> { |
|
||||
|
|
||||
List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(List<SchemeType> domainSchemes, String domainName, String pkgName, PlatformType platformType); |
|
||||
|
|
||||
List<OAuth2Registration> findByOAuth2ParamsId(UUID oauth2ParamsId); |
|
||||
|
|
||||
String findAppSecret(UUID id, String pkgName); |
|
||||
|
|
||||
} |
|
||||
@ -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 jakarta.transaction.Transactional; |
|
||||
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 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,80 @@ |
|||||
|
/** |
||||
|
* 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.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.OAuth2Client; |
||||
|
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 Oauth2ClientDataValidator extends DataValidator<OAuth2Client> { |
||||
|
|
||||
|
@Override |
||||
|
protected void validateDataImpl(TenantId tenantId, OAuth2Client oAuth2Client) { |
||||
|
OAuth2MapperConfig mapperConfig = oAuth2Client.getMapperConfig(); |
||||
|
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!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue