1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.encrypt.merge.dql;
19
20 import lombok.RequiredArgsConstructor;
21 import org.apache.shardingsphere.encrypt.exception.data.DecryptFailedException;
22 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
23 import org.apache.shardingsphere.encrypt.rule.column.EncryptColumn;
24 import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
25 import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
26 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
27 import org.apache.shardingsphere.infra.exception.core.external.sql.identifier.SQLExceptionIdentifier;
28 import org.apache.shardingsphere.infra.merge.result.MergedResult;
29 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
30
31 import java.io.InputStream;
32 import java.io.Reader;
33 import java.sql.SQLException;
34 import java.util.Calendar;
35 import java.util.Optional;
36
37
38
39
40 @RequiredArgsConstructor
41 public final class EncryptMergedResult implements MergedResult {
42
43 private final ShardingSphereDatabase database;
44
45 private final EncryptRule encryptRule;
46
47 private final SelectStatementContext selectStatementContext;
48
49 private final MergedResult mergedResult;
50
51 @Override
52 public boolean next() throws SQLException {
53 return mergedResult.next();
54 }
55
56 @Override
57 public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
58 Optional<ColumnProjection> columnProjection = selectStatementContext.findColumnProjection(columnIndex);
59 if (!columnProjection.isPresent()) {
60 return mergedResult.getValue(columnIndex, type);
61 }
62 String originalTableName = columnProjection.get().getOriginalTable().getValue();
63 String originalColumnName = columnProjection.get().getOriginalColumn().getValue();
64 if (!encryptRule.findEncryptTable(originalTableName).map(optional -> optional.isEncryptColumn(originalColumnName)).orElse(false)) {
65 return mergedResult.getValue(columnIndex, type);
66 }
67 Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
68 EncryptColumn encryptColumn = encryptRule.getEncryptTable(originalTableName).getEncryptColumn(originalColumnName);
69 String schemaName =
70 selectStatementContext.getTablesContext().getSchemaName().orElseGet(() -> new DatabaseTypeRegistry(selectStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName()));
71 try {
72 return encryptColumn.getCipher().decrypt(database.getName(), schemaName, originalTableName, originalColumnName, cipherValue);
73
74 } catch (final Exception ex) {
75
76 throw new DecryptFailedException(String.valueOf(cipherValue), new SQLExceptionIdentifier(database.getName(), originalTableName, originalColumnName), ex);
77 }
78 }
79
80 @Override
81 public Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
82 return mergedResult.getCalendarValue(columnIndex, type, calendar);
83 }
84
85 @Override
86 public InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
87 return mergedResult.getInputStream(columnIndex, type);
88 }
89
90 @Override
91 public Reader getCharacterStream(final int columnIndex) throws SQLException {
92 return mergedResult.getCharacterStream(columnIndex);
93 }
94
95 @Override
96 public boolean wasNull() throws SQLException {
97 return mergedResult.wasNull();
98 }
99 }