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