143 changed files with 858 additions and 1120 deletions
@ -0,0 +1,96 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 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 org.junit.Assert; |
||||
|
import org.junit.Test; |
||||
|
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.common.data.queue.ProcessingStrategy; |
||||
|
import org.thingsboard.server.common.data.queue.ProcessingStrategyType; |
||||
|
import org.thingsboard.server.common.data.queue.Queue; |
||||
|
import org.thingsboard.server.common.data.queue.SubmitStrategy; |
||||
|
import org.thingsboard.server.common.data.queue.SubmitStrategyType; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
|
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
|
||||
|
@DaoSqlTest |
||||
|
public class BaseQueueControllerTest extends AbstractControllerTest { |
||||
|
|
||||
|
@Test |
||||
|
public void testQueueWithServiceTypeRE() throws Exception { |
||||
|
loginSysAdmin(); |
||||
|
|
||||
|
// create queue
|
||||
|
Queue queue = new Queue(); |
||||
|
queue.setName("qwerty"); |
||||
|
queue.setTopic("tb_rule_engine.qwerty"); |
||||
|
queue.setPollInterval(25); |
||||
|
queue.setPartitions(10); |
||||
|
queue.setTenantId(TenantId.SYS_TENANT_ID); |
||||
|
queue.setConsumerPerPartition(false); |
||||
|
queue.setPackProcessingTimeout(2000); |
||||
|
SubmitStrategy submitStrategy = new SubmitStrategy(); |
||||
|
submitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); |
||||
|
queue.setSubmitStrategy(submitStrategy); |
||||
|
ProcessingStrategy processingStrategy = new ProcessingStrategy(); |
||||
|
processingStrategy.setType(ProcessingStrategyType.RETRY_ALL); |
||||
|
processingStrategy.setRetries(3); |
||||
|
processingStrategy.setFailurePercentage(0.7); |
||||
|
processingStrategy.setPauseBetweenRetries(3); |
||||
|
processingStrategy.setMaxPauseBetweenRetries(5); |
||||
|
queue.setProcessingStrategy(processingStrategy); |
||||
|
|
||||
|
// create queue
|
||||
|
Queue queue2 = new Queue(); |
||||
|
queue2.setName("qwerty2"); |
||||
|
queue2.setTopic("tb_rule_engine.qwerty2"); |
||||
|
queue2.setPollInterval(25); |
||||
|
queue2.setPartitions(10); |
||||
|
queue2.setTenantId(TenantId.SYS_TENANT_ID); |
||||
|
queue2.setConsumerPerPartition(false); |
||||
|
queue2.setPackProcessingTimeout(2000); |
||||
|
submitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); |
||||
|
queue2.setSubmitStrategy(submitStrategy); |
||||
|
processingStrategy.setType(ProcessingStrategyType.RETRY_ALL); |
||||
|
processingStrategy.setRetries(3); |
||||
|
processingStrategy.setFailurePercentage(0.7); |
||||
|
processingStrategy.setPauseBetweenRetries(3); |
||||
|
processingStrategy.setMaxPauseBetweenRetries(5); |
||||
|
queue2.setProcessingStrategy(processingStrategy); |
||||
|
|
||||
|
Queue savedQueue = doPost("/api/queues?serviceType=" + "TB-RULE-ENGINE", queue, Queue.class); |
||||
|
Queue savedQueue2 = doPost("/api/queues?serviceType=" + "TB_RULE_ENGINE", queue2, Queue.class); |
||||
|
|
||||
|
PageLink pageLink = new PageLink(10); |
||||
|
PageData<Queue> pageData; |
||||
|
pageData = doGetTypedWithPageLink("/api/queues?serviceType=TB-RULE-ENGINE&", new TypeReference<>() { |
||||
|
}, pageLink); |
||||
|
Assert.assertFalse(pageData.getData().isEmpty()); |
||||
|
doDelete("/api/queues/" + savedQueue.getUuidId()) |
||||
|
.andExpect(status().isOk()); |
||||
|
|
||||
|
pageData = doGetTypedWithPageLink("/api/queues?serviceType=TB_RULE_ENGINE&", new TypeReference<>() { |
||||
|
}, pageLink); |
||||
|
Assert.assertFalse(pageData.getData().isEmpty()); |
||||
|
doDelete("/api/queues/" + savedQueue2.getUuidId()) |
||||
|
.andExpect(status().isOk()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 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.security.auth.oauth2; |
||||
|
|
||||
|
import org.junit.Test; |
||||
|
import org.mockito.Mockito; |
||||
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; |
||||
|
|
||||
|
import javax.servlet.http.Cookie; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import static org.junit.Assert.assertEquals; |
||||
|
import static org.junit.Assert.assertNotNull; |
||||
|
import static org.thingsboard.server.service.security.auth.oauth2.HttpCookieOAuth2AuthorizationRequestRepository.OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME; |
||||
|
|
||||
|
public class CookieUtilsTest { |
||||
|
|
||||
|
@Test |
||||
|
public void serializeDeserializeOAuth2AuthorizationRequestTest() { |
||||
|
HttpCookieOAuth2AuthorizationRequestRepository cookieRequestRepo = new HttpCookieOAuth2AuthorizationRequestRepository(); |
||||
|
HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class); |
||||
|
|
||||
|
Map<String, Object> additionalParameters = new LinkedHashMap<>(); |
||||
|
additionalParameters.put("param1", "value1"); |
||||
|
additionalParameters.put("param2", "value2"); |
||||
|
var request = OAuth2AuthorizationRequest.authorizationCode() |
||||
|
.authorizationUri("testUri").clientId("testId") |
||||
|
.scope("read", "write") |
||||
|
.additionalParameters(additionalParameters).build(); |
||||
|
|
||||
|
|
||||
|
Cookie cookie = new Cookie(OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME, CookieUtils.serialize(request)); |
||||
|
Mockito.when(servletRequest.getCookies()).thenReturn(new Cookie[]{cookie}); |
||||
|
|
||||
|
OAuth2AuthorizationRequest deserializedRequest = cookieRequestRepo.loadAuthorizationRequest(servletRequest); |
||||
|
|
||||
|
assertNotNull(deserializedRequest); |
||||
|
assertEquals(request.getGrantType(), deserializedRequest.getGrantType()); |
||||
|
assertEquals(request.getAuthorizationUri(), deserializedRequest.getAuthorizationUri()); |
||||
|
assertEquals(request.getClientId(), deserializedRequest.getClientId()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -1,66 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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.security.auth.oauth2; |
|
||||
|
|
||||
import org.junit.Before; |
|
||||
import org.junit.Test; |
|
||||
import org.mockito.Mockito; |
|
||||
|
|
||||
import javax.servlet.http.Cookie; |
|
||||
import javax.servlet.http.HttpServletRequest; |
|
||||
import java.io.IOException; |
|
||||
import java.io.ObjectInputStream; |
|
||||
import java.io.Serializable; |
|
||||
|
|
||||
import static org.junit.Assert.assertEquals; |
|
||||
import static org.thingsboard.server.service.security.auth.oauth2.HttpCookieOAuth2AuthorizationRequestRepository.OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME; |
|
||||
|
|
||||
public class HttpCookieOAuth2AuthorizationRequestRepositoryTest { |
|
||||
|
|
||||
private static final String SERIALIZED_ATTACK_STRING = |
|
||||
"rO0ABXNyAHVvcmcudGhpbmdzYm9hcmQuc2VydmVyLnNlcnZpY2Uuc2VjdXJpdHkuYXV0aC5vYXV0aDIuSHR0cENvb2tpZU9BdXRoMkF1dGhvcml6YXRpb25SZXF1ZXN0UmVwb3NpdG9yeVRlc3QkTWFsaWNpb3VzQ2xhc3MAAAAAAAAAAAIAAHhw"; |
|
||||
|
|
||||
private static int maliciousMethodInvocationCounter; |
|
||||
|
|
||||
@Before |
|
||||
public void resetInvocationCounter() { |
|
||||
maliciousMethodInvocationCounter = 0; |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void whenLoadAuthorizationRequest_thenMaliciousMethodNotInvoked() { |
|
||||
HttpCookieOAuth2AuthorizationRequestRepository cookieRequestRepo = new HttpCookieOAuth2AuthorizationRequestRepository(); |
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
|
||||
Cookie cookie = new Cookie(OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME, SERIALIZED_ATTACK_STRING); |
|
||||
Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie}); |
|
||||
|
|
||||
cookieRequestRepo.loadAuthorizationRequest(request); |
|
||||
|
|
||||
assertEquals(0, maliciousMethodInvocationCounter); |
|
||||
} |
|
||||
|
|
||||
private static class MaliciousClass implements Serializable { |
|
||||
private static final long serialVersionUID = 0L; |
|
||||
|
|
||||
public void maliciousMethod() { |
|
||||
maliciousMethodInvocationCounter++; |
|
||||
} |
|
||||
|
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { |
|
||||
maliciousMethod(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,40 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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; |
|
||||
|
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|
||||
import org.thingsboard.server.common.data.id.UUIDBased; |
|
||||
|
|
||||
public abstract class SearchTextBased<I extends UUIDBased> extends BaseData<I> { |
|
||||
|
|
||||
private static final long serialVersionUID = -539812997348227609L; |
|
||||
|
|
||||
public SearchTextBased() { |
|
||||
super(); |
|
||||
} |
|
||||
|
|
||||
public SearchTextBased(I id) { |
|
||||
super(id); |
|
||||
} |
|
||||
|
|
||||
public SearchTextBased(SearchTextBased<I> searchTextBased) { |
|
||||
super(searchTextBased); |
|
||||
} |
|
||||
|
|
||||
@JsonIgnore |
|
||||
public abstract String getSearchText(); |
|
||||
|
|
||||
} |
|
||||
@ -1,108 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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; |
|
||||
|
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
|
||||
import com.fasterxml.jackson.databind.JsonNode; |
|
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.thingsboard.server.common.data.id.UUIDBased; |
|
||||
import org.thingsboard.server.common.data.validation.NoXss; |
|
||||
|
|
||||
import java.io.ByteArrayInputStream; |
|
||||
import java.io.IOException; |
|
||||
import java.util.Arrays; |
|
||||
import java.util.Objects; |
|
||||
import java.util.function.Consumer; |
|
||||
import java.util.function.Supplier; |
|
||||
|
|
||||
/** |
|
||||
* Created by ashvayka on 19.02.18. |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> extends SearchTextBased<I> implements HasAdditionalInfo { |
|
||||
|
|
||||
public static final ObjectMapper mapper = new ObjectMapper(); |
|
||||
@NoXss |
|
||||
private transient JsonNode additionalInfo; |
|
||||
@JsonIgnore |
|
||||
private byte[] additionalInfoBytes; |
|
||||
|
|
||||
public SearchTextBasedWithAdditionalInfo() { |
|
||||
super(); |
|
||||
} |
|
||||
|
|
||||
public SearchTextBasedWithAdditionalInfo(I id) { |
|
||||
super(id); |
|
||||
} |
|
||||
|
|
||||
public SearchTextBasedWithAdditionalInfo(SearchTextBasedWithAdditionalInfo<I> searchTextBased) { |
|
||||
super(searchTextBased); |
|
||||
setAdditionalInfo(searchTextBased.getAdditionalInfo()); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public JsonNode getAdditionalInfo() { |
|
||||
return getJson(() -> additionalInfo, () -> additionalInfoBytes); |
|
||||
} |
|
||||
|
|
||||
public void setAdditionalInfo(JsonNode addInfo) { |
|
||||
setJson(addInfo, json -> this.additionalInfo = json, bytes -> this.additionalInfoBytes = bytes); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public boolean equals(Object o) { |
|
||||
if (this == o) return true; |
|
||||
if (o == null || getClass() != o.getClass()) return false; |
|
||||
if (!super.equals(o)) return false; |
|
||||
SearchTextBasedWithAdditionalInfo<?> that = (SearchTextBasedWithAdditionalInfo<?>) o; |
|
||||
return Arrays.equals(additionalInfoBytes, that.additionalInfoBytes); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public int hashCode() { |
|
||||
return Objects.hash(super.hashCode(), additionalInfoBytes); |
|
||||
} |
|
||||
|
|
||||
public static JsonNode getJson(Supplier<JsonNode> jsonData, Supplier<byte[]> binaryData) { |
|
||||
JsonNode json = jsonData.get(); |
|
||||
if (json != null) { |
|
||||
return json; |
|
||||
} else { |
|
||||
byte[] data = binaryData.get(); |
|
||||
if (data != null) { |
|
||||
try { |
|
||||
return mapper.readTree(new ByteArrayInputStream(data)); |
|
||||
} catch (IOException e) { |
|
||||
log.warn("Can't deserialize json data: ", e); |
|
||||
return null; |
|
||||
} |
|
||||
} else { |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static void setJson(JsonNode json, Consumer<JsonNode> jsonConsumer, Consumer<byte[]> bytesConsumer) { |
|
||||
jsonConsumer.accept(json); |
|
||||
try { |
|
||||
bytesConsumer.accept(mapper.writeValueAsBytes(json)); |
|
||||
} catch (JsonProcessingException e) { |
|
||||
log.warn("Can't serialize json data: ", e); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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; |
|
||||
|
|
||||
public interface SearchTextEntity<D> extends BaseEntity<D> { |
|
||||
|
|
||||
String getSearchTextSource(); |
|
||||
|
|
||||
void setSearchText(String searchText); |
|
||||
|
|
||||
} |
|
||||
@ -1,30 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.dao.sql; |
|
||||
|
|
||||
import org.thingsboard.server.dao.model.BaseEntity; |
|
||||
import org.thingsboard.server.dao.model.SearchTextEntity; |
|
||||
|
|
||||
/** |
|
||||
* Created by Valerii Sosliuk on 5/6/2017. |
|
||||
*/ |
|
||||
public abstract class JpaAbstractSearchTextDao <E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> { |
|
||||
|
|
||||
@Override |
|
||||
protected void setSearchText(E entity) { |
|
||||
((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase()); |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue