zhuyifan

fix(security): 修复登录拦截器中的权限验证问题

Showing 170 changed files with 27 additions and 48 deletions
...@@ -3,4 +3,4 @@ org.gradle.parallel=true ...@@ -3,4 +3,4 @@ org.gradle.parallel=true
3 org.gradle.caching=true 3 org.gradle.caching=true
4 org.gradle.jvmargs=-Xmx3096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 4 org.gradle.jvmargs=-Xmx3096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
5 org.gradle.configureondemand=true 5 org.gradle.configureondemand=true
6 -org.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64
...\ No newline at end of file ...\ No newline at end of file
6 +#org.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,7 +7,6 @@ import com.infoloop.tianting.intercepter.LoginInterceptor; ...@@ -7,7 +7,6 @@ import com.infoloop.tianting.intercepter.LoginInterceptor;
7 import com.infoloop.tianting.intercepter.RequestMonitor; 7 import com.infoloop.tianting.intercepter.RequestMonitor;
8 import com.infoloop.tianting.intercepter.ResourceInjector; 8 import com.infoloop.tianting.intercepter.ResourceInjector;
9 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient; 9 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
10 -import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
11 import com.infoloop.tianting.service.client.OperatorServiceRpcClient; 10 import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
12 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient; 11 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
13 import com.infoloop.tianting.tracing.HttpTracingInterceptor; 12 import com.infoloop.tianting.tracing.HttpTracingInterceptor;
...@@ -37,13 +36,12 @@ public class WebMvcConfig implements WebMvcConfigurer { ...@@ -37,13 +36,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
37 final ResourceInjector resourceInjector, 36 final ResourceInjector resourceInjector,
38 final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient, 37 final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient,
39 final OperatorServiceRpcClient operatorServiceRpcClient, 38 final OperatorServiceRpcClient operatorServiceRpcClient,
40 - final WOperatorServiceRpcClient wOperatorServiceRpcClient, 39 + final WOperatorServiceRpcClient wOperatorServiceRpcClient) {
41 - final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient) {
42 this.httpInterceptors = new ArrayList<>(); 40 this.httpInterceptors = new ArrayList<>();
43 this.httpInterceptors.add(new HttpTracingInterceptor(tracing)); 41 this.httpInterceptors.add(new HttpTracingInterceptor(tracing));
44 this.httpInterceptors.add(new RequestMonitor()); 42 this.httpInterceptors.add(new RequestMonitor());
45 this.httpInterceptors.add(new ApiSignInterceptor()); 43 this.httpInterceptors.add(new ApiSignInterceptor());
46 - this.httpInterceptors.add(new LoginInterceptor(clientCustomerServiceRpcClient, meiZhongYiHeServiceClient, operatorServiceRpcClient, wOperatorServiceRpcClient)); 44 + this.httpInterceptors.add(new LoginInterceptor(clientCustomerServiceRpcClient, operatorServiceRpcClient, wOperatorServiceRpcClient));
47 this.httpInterceptors.add(resourceInjector); 45 this.httpInterceptors.add(resourceInjector);
48 46
49 } 47 }
......
1 package com.infoloop.tianting.controller; 1 package com.infoloop.tianting.controller;
2 2
3 import com.github.xiaoymin.knife4j.annotations.ApiSupport; 3 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
4 -import com.infoloop.tianting.model.dto.ClientLabelDTO;
5 -import com.infoloop.tianting.model.dto.ClientLabelDTO.LabelDto;
6 import com.infoloop.tianting.model.dto.KdsDTO; 4 import com.infoloop.tianting.model.dto.KdsDTO;
7 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto; 5 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto;
8 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto; 6 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto;
...@@ -10,8 +8,6 @@ import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderSkuDto; ...@@ -10,8 +8,6 @@ import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderSkuDto;
10 import com.infoloop.tianting.service.KdsService; 8 import com.infoloop.tianting.service.KdsService;
11 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
12 import io.swagger.annotations.ApiOperation; 10 import io.swagger.annotations.ApiOperation;
13 -import java.util.List;
14 -import javax.validation.Valid;
15 import lombok.RequiredArgsConstructor; 11 import lombok.RequiredArgsConstructor;
16 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
17 import org.springframework.beans.factory.annotation.Autowired; 13 import org.springframework.beans.factory.annotation.Autowired;
...@@ -22,6 +18,9 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -22,6 +18,9 @@ import org.springframework.web.bind.annotation.RequestBody;
22 import org.springframework.web.bind.annotation.ResponseStatus; 18 import org.springframework.web.bind.annotation.ResponseStatus;
23 import org.springframework.web.bind.annotation.RestController; 19 import org.springframework.web.bind.annotation.RestController;
24 20
21 +import javax.validation.Valid;
22 +import java.util.List;
23 +
25 @Api(tags = "KDS") 24 @Api(tags = "KDS")
26 @ApiSupport(order = -1) 25 @ApiSupport(order = -1)
27 @Slf4j 26 @Slf4j
......
...@@ -53,7 +53,6 @@ public class PayController { ...@@ -53,7 +53,6 @@ public class PayController {
53 return payServiceClient.callback(paymentCallbackDTO); 53 return payServiceClient.callback(paymentCallbackDTO);
54 } 54 }
55 55
56 - @SaIgnore
57 @ApiOperation(value = "支付撤销") 56 @ApiOperation(value = "支付撤销")
58 @PostMapping(value = "/pay/cancel") 57 @PostMapping(value = "/pay/cancel")
59 @ResponseStatus(HttpStatus.OK) 58 @ResponseStatus(HttpStatus.OK)
......
...@@ -34,7 +34,9 @@ public enum ErrorCodeEnum implements BaseEnum { ...@@ -34,7 +34,9 @@ public enum ErrorCodeEnum implements BaseEnum {
34 34
35 SKUS_STOCK_NO_ENOUGH_TODAY(406000008, "下单菜品: {0} 库存不足"), 35 SKUS_STOCK_NO_ENOUGH_TODAY(406000008, "下单菜品: {0} 库存不足"),
36 36
37 - ORDER_CANCEL(406000009, "订单已自动取消") 37 + ORDER_CANCEL(406000009, "订单已自动取消"),
38 +
39 + ORDER_PAY_CANCEL_FAILED(406000010, "支付撤销失败")
38 ; 40 ;
39 private final int code; 41 private final int code;
40 42
......
...@@ -6,15 +6,13 @@ import cn.dev33.satoken.exception.SaTokenException; ...@@ -6,15 +6,13 @@ import cn.dev33.satoken.exception.SaTokenException;
6 import cn.dev33.satoken.stp.StpUtil; 6 import cn.dev33.satoken.stp.StpUtil;
7 import cn.dev33.satoken.strategy.SaStrategy; 7 import cn.dev33.satoken.strategy.SaStrategy;
8 import cn.hutool.core.convert.Convert; 8 import cn.hutool.core.convert.Convert;
9 -import com.infoloop.rpc.meizhongyiheservice.HospitalStatus;
10 -import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordHospitalStatusEnum;
11 import com.infoloop.tianting.constant.CommonConstants; 9 import com.infoloop.tianting.constant.CommonConstants;
12 import com.infoloop.tianting.context.LoginContextHolder; 10 import com.infoloop.tianting.context.LoginContextHolder;
13 import com.infoloop.tianting.enums.LoginSourceEnum; 11 import com.infoloop.tianting.enums.LoginSourceEnum;
12 +import com.infoloop.tianting.exception.ClientEndExceptions;
14 import com.infoloop.tianting.exception.ErrorCodeEnum; 13 import com.infoloop.tianting.exception.ErrorCodeEnum;
15 import com.infoloop.tianting.model.common.ResponseResult; 14 import com.infoloop.tianting.model.common.ResponseResult;
16 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient; 15 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
17 -import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
18 import com.infoloop.tianting.service.client.OperatorServiceRpcClient; 16 import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
19 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient; 17 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
20 import com.infoloop.tianting.utils.ResponseUtil; 18 import com.infoloop.tianting.utils.ResponseUtil;
...@@ -36,7 +34,6 @@ import java.io.IOException; ...@@ -36,7 +34,6 @@ import java.io.IOException;
36 public class LoginInterceptor extends HandlerInterceptorAdapter { 34 public class LoginInterceptor extends HandlerInterceptorAdapter {
37 35
38 private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient; 36 private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
39 - private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient;
40 private final OperatorServiceRpcClient operatorServiceRpcClient; 37 private final OperatorServiceRpcClient operatorServiceRpcClient;
41 private final WOperatorServiceRpcClient wOperatorServiceRpcClient; 38 private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
42 39
...@@ -76,20 +73,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -76,20 +73,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
76 final var customer = clientCustomerServiceRpcClient.getClientCustomerById(enterpriseId, loginId); 73 final var customer = clientCustomerServiceRpcClient.getClientCustomerById(enterpriseId, loginId);
77 if (customer == null) { 74 if (customer == null) {
78 response.setStatus(HttpStatus.FORBIDDEN.value()); 75 response.setStatus(HttpStatus.FORBIDDEN.value());
79 - ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN)); 76 + ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.VALIDATE_FAILED));
80 - return false;
81 - }
82 - var record = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId(customer.getResponse().getEnterpriseId(), customer.getResponse().getId());
83 - if (!record.hasResponse() || record.getResponse().getHospitalStatus() != ClientCustomerHospitalRecordHospitalStatusEnum.CURRENT) {
84 - response.setStatus(HttpStatus.FORBIDDEN.value());
85 - ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
86 - return false;
87 - }
88 - //还需要去读取HIS系统最新用户住院信息
89 - final var hisCustomerHospitalRecord = meiZhongYiHeServiceClient.getCustomerDetailById(customer.getResponse().getHISCustomerId(), record.getResponse().getContractNo()).getCustomerHospitalRecord();
90 - if (hisCustomerHospitalRecord.getHospitalStatus() != HospitalStatus.CURRENT) {
91 - response.setStatus(HttpStatus.FORBIDDEN.value());
92 - ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
93 return false; 77 return false;
94 } 78 }
95 builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER); 79 builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER);
...@@ -99,7 +83,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -99,7 +83,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
99 final var opeartor = operatorServiceRpcClient.getCOperatorById(loginId); 83 final var opeartor = operatorServiceRpcClient.getCOperatorById(loginId);
100 if (opeartor == null) { 84 if (opeartor == null) {
101 response.setStatus(HttpStatus.FORBIDDEN.value()); 85 response.setStatus(HttpStatus.FORBIDDEN.value());
102 - ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN)); 86 + ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.VALIDATE_FAILED));
103 return false; 87 return false;
104 } 88 }
105 builder.id(loginId).enterpriseId(enterpriseId).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR); 89 builder.id(loginId).enterpriseId(enterpriseId).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR);
...@@ -108,9 +92,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -108,9 +92,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
108 final var loginId = StpUtil.getLoginIdAsInt(); 92 final var loginId = StpUtil.getLoginIdAsInt();
109 final var operator = wOperatorServiceRpcClient.getWOperatorById(loginId).getResponse(); 93 final var operator = wOperatorServiceRpcClient.getWOperatorById(loginId).getResponse();
110 if (operator.getId() == 0) { 94 if (operator.getId() == 0) {
111 - response.setStatus(HttpStatus.FORBIDDEN.value()); 95 + throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.UNAUTHORIZED.name());
112 - ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
113 - return false;
114 } 96 }
115 builder.id(loginId).enterpriseId(enterpriseId).name(operator.getName()).loginSource(LoginSourceEnum.KDS); 97 builder.id(loginId).enterpriseId(enterpriseId).name(operator.getName()).loginSource(LoginSourceEnum.KDS);
116 return true; 98 return true;
......
...@@ -4,12 +4,13 @@ import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordH ...@@ -4,12 +4,13 @@ import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordH
4 import com.infoloop.tianting.clientcustomerservice.ClientCustomerSexEnum; 4 import com.infoloop.tianting.clientcustomerservice.ClientCustomerSexEnum;
5 import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDto; 5 import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDto;
6 import io.swagger.annotations.ApiModel; 6 import io.swagger.annotations.ApiModel;
7 -import java.util.List;
8 import lombok.AllArgsConstructor; 7 import lombok.AllArgsConstructor;
9 import lombok.Builder; 8 import lombok.Builder;
10 import lombok.Data; 9 import lombok.Data;
11 import lombok.NoArgsConstructor; 10 import lombok.NoArgsConstructor;
12 11
12 +import java.util.List;
13 +
13 @Data 14 @Data
14 @ApiModel(description = "ClientCustomerDTO") 15 @ApiModel(description = "ClientCustomerDTO")
15 public class ClientCustomerDbDTO { 16 public class ClientCustomerDbDTO {
......
...@@ -5,12 +5,12 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum; ...@@ -5,12 +5,12 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum;
5 import com.infoloop.tianting.deliveryruleservice.ClientDishLabelStatusEnum; 5 import com.infoloop.tianting.deliveryruleservice.ClientDishLabelStatusEnum;
6 import com.infoloop.tianting.deliveryruleservice.ClientLabelTypeEnum; 6 import com.infoloop.tianting.deliveryruleservice.ClientLabelTypeEnum;
7 import io.swagger.annotations.ApiModel; 7 import io.swagger.annotations.ApiModel;
8 -import io.swagger.models.auth.In;
9 -import java.util.List;
10 import lombok.Builder; 8 import lombok.Builder;
11 import lombok.Data; 9 import lombok.Data;
12 import lombok.ToString; 10 import lombok.ToString;
13 11
12 +import java.util.List;
13 +
14 @Data 14 @Data
15 @ApiModel(description = "标签DTO") 15 @ApiModel(description = "标签DTO")
16 public class ClientLabelDTO { 16 public class ClientLabelDTO {
......
...@@ -3,11 +3,11 @@ package com.infoloop.tianting.model.dto; ...@@ -3,11 +3,11 @@ package com.infoloop.tianting.model.dto;
3 import com.infoloop.tianting.clientinventoryservice.ClientType; 3 import com.infoloop.tianting.clientinventoryservice.ClientType;
4 import com.infoloop.tianting.clientinventoryservice.CustomerSource; 4 import com.infoloop.tianting.clientinventoryservice.CustomerSource;
5 import io.swagger.annotations.ApiModel; 5 import io.swagger.annotations.ApiModel;
6 -import io.swagger.models.auth.In;
7 -import java.util.List;
8 import lombok.Builder; 6 import lombok.Builder;
9 import lombok.Data; 7 import lombok.Data;
10 8
9 +import java.util.List;
10 +
11 @Data 11 @Data
12 @ApiModel(description = "院区DTO") 12 @ApiModel(description = "院区DTO")
13 public class InventoryDbDTO { 13 public class InventoryDbDTO {
......
...@@ -6,13 +6,13 @@ import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto; ...@@ -6,13 +6,13 @@ import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
6 import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerDetailDto; 6 import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerDetailDto;
7 import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerNotice; 7 import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerNotice;
8 import io.swagger.annotations.ApiModel; 8 import io.swagger.annotations.ApiModel;
9 -import io.swagger.models.auth.In;
10 -import java.util.List;
11 import lombok.AllArgsConstructor; 9 import lombok.AllArgsConstructor;
12 import lombok.Builder; 10 import lombok.Builder;
13 import lombok.Data; 11 import lombok.Data;
14 import lombok.NoArgsConstructor; 12 import lombok.NoArgsConstructor;
15 13
14 +import java.util.List;
15 +
16 @Data 16 @Data
17 @ApiModel(description = "kds DTO") 17 @ApiModel(description = "kds DTO")
18 public class KdsDTO { 18 public class KdsDTO {
......
...@@ -2,11 +2,12 @@ package com.infoloop.tianting.model.dto; ...@@ -2,11 +2,12 @@ package com.infoloop.tianting.model.dto;
2 2
3 import com.infoloop.tianting.setmealscheduleservice.MealStatus; 3 import com.infoloop.tianting.setmealscheduleservice.MealStatus;
4 import io.swagger.annotations.ApiModel; 4 import io.swagger.annotations.ApiModel;
5 -import java.util.List;
6 import lombok.Builder; 5 import lombok.Builder;
7 import lombok.Data; 6 import lombok.Data;
8 import lombok.ToString; 7 import lombok.ToString;
9 8
9 +import java.util.List;
10 +
10 @Data 11 @Data
11 @ApiModel(description = "餐别相关DTO") 12 @ApiModel(description = "餐别相关DTO")
12 public class MealDbDTO { 13 public class MealDbDTO {
......
...@@ -2,14 +2,13 @@ package com.infoloop.tianting.model.dto; ...@@ -2,14 +2,13 @@ package com.infoloop.tianting.model.dto;
2 2
3 import com.infoloop.tianting.clientcustomerorderservice.OrderOperationType; 3 import com.infoloop.tianting.clientcustomerorderservice.OrderOperationType;
4 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum; 4 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum;
5 -import com.infoloop.tianting.model.dto.MenuDbDTO.DishRuleJson;
6 -import com.infoloop.tianting.model.dto.MenuDbDTO.OrderRuleJson;
7 import io.swagger.annotations.ApiModel; 5 import io.swagger.annotations.ApiModel;
8 -import java.util.List;
9 import lombok.Builder; 6 import lombok.Builder;
10 import lombok.Data; 7 import lombok.Data;
11 import lombok.ToString; 8 import lombok.ToString;
12 9
10 +import java.util.List;
11 +
13 @Data 12 @Data
14 @ApiModel(description = "操作记录DTO") 13 @ApiModel(description = "操作记录DTO")
15 public class OperationDTO { 14 public class OperationDTO {
......
...@@ -2,13 +2,13 @@ package com.infoloop.tianting.model.dto; ...@@ -2,13 +2,13 @@ package com.infoloop.tianting.model.dto;
2 2
3 import com.infoloop.tianting.enums.SettlementDimensionEnum; 3 import com.infoloop.tianting.enums.SettlementDimensionEnum;
4 import io.swagger.annotations.ApiModel; 4 import io.swagger.annotations.ApiModel;
5 -import java.util.ArrayList;
6 -import java.util.Map;
7 import lombok.Builder; 5 import lombok.Builder;
8 import lombok.Data; 6 import lombok.Data;
9 7
10 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
9 +import java.util.ArrayList;
11 import java.util.List; 10 import java.util.List;
11 +import java.util.Map;
12 12
13 @Data 13 @Data
14 @ApiModel(description = "统计DTO") 14 @ApiModel(description = "统计DTO")
......
1 package com.infoloop.tianting.model.dto; 1 package com.infoloop.tianting.model.dto;
2 2
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 -import io.swagger.annotations.ApiModelProperty;
5 -import io.swagger.models.auth.In;
6 import lombok.AllArgsConstructor; 4 import lombok.AllArgsConstructor;
7 import lombok.Builder; 5 import lombok.Builder;
8 import lombok.Data; 6 import lombok.Data;
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.