-
Notifications
You must be signed in to change notification settings - Fork 392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<fix>[encrypt]: recover iam2 attarbute data #1328
Open
MatheMatrix
wants to merge
1
commit into
zstackio:master
Choose a base branch
from
MatheMatrix:bug/encrypt-iam
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,73 @@ | ||
alter table LicenseHistoryVO modify COLUMN `userName` varchar(64) NOT NULL; | ||
|
||
ALTER TABLE LicenseHistoryVO ADD COLUMN capacity int(10) NOT NULL; | ||
|
||
CREATE TABLE IF NOT EXISTS `zstack`.`IAM2VirtualIDInformationVO` ( | ||
`uuid` varchar(32) NOT NULL UNIQUE, | ||
`phone` varchar(255), | ||
`mail` varchar(255), | ||
PRIMARY KEY (`uuid`), | ||
CONSTRAINT `fkIAM2VirtualIDInformationVOIAM2VirtualIDVO` FOREIGN KEY (`uuid`) REFERENCES `IAM2VirtualIDVO` (`uuid`) ON DELETE CASCADE | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
|
||
DELIMITER $$ | ||
CREATE PROCEDURE attributePhoneToInformation() | ||
BEGIN | ||
DECLARE vitualIdPhone VARCHAR(32); | ||
DECLARE vitualIdUuid VARCHAR(32); | ||
DECLARE done INT DEFAULT FALSE; | ||
DECLARE phoneCursor CURSOR FOR SELECT virtualIDUuid, value from `zstack`.`IAM2VirtualIDAttributeVO` WHERE name = "phone"; | ||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; | ||
|
||
open phoneCursor; | ||
read_loop: LOOP | ||
FETCH phoneCursor INTO vitualIdUuid, vitualIdPhone; | ||
IF done THEN | ||
LEAVE read_loop; | ||
END IF; | ||
|
||
IF (select count(*) from IAM2VirtualIDInformationVO where uuid = vitualIdUuid) = 0 THEN | ||
INSERT `zstack`.`IAM2VirtualIDInformationVO`(uuid, phone) values (vitualIdUuid, vitualIdPhone); | ||
else | ||
update `zstack`.`IAM2VirtualIDInformationVO` set phone = vitualIdPhone where uuid = vitualIdUuid; | ||
END IF; | ||
|
||
END LOOP; | ||
close phoneCursor; | ||
SELECT CURTIME(); | ||
END $$ | ||
DELIMITER ; | ||
|
||
call attributePhoneToInformation(); | ||
DROP PROCEDURE IF EXISTS attributePhoneToInformation; | ||
|
||
DELIMITER $$ | ||
CREATE PROCEDURE attributeMailToInformation() | ||
BEGIN | ||
DECLARE vitualIdMail VARCHAR(32); | ||
DECLARE vitualIdUuid VARCHAR(32); | ||
DECLARE done INT DEFAULT FALSE; | ||
DECLARE mailCursor CURSOR FOR SELECT virtualIDUuid, value from `zstack`.`IAM2VirtualIDAttributeVO` WHERE name = "mail"; | ||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; | ||
|
||
open mailCursor; | ||
read_loop: LOOP | ||
FETCH mailCursor INTO vitualIdUuid, vitualIdMail; | ||
IF done THEN | ||
LEAVE read_loop; | ||
END IF; | ||
|
||
IF (select count(*) from IAM2VirtualIDInformationVO where uuid = vitualIdUuid) = 0 THEN | ||
INSERT `zstack`.`IAM2VirtualIDInformationVO`(uuid, mail) values (vitualIdUuid, vitualIdMail); | ||
ELSE | ||
update `zstack`.`IAM2VirtualIDInformationVO` set mail = vitualIdMail where uuid = vitualIdUuid; | ||
END IF; | ||
|
||
END LOOP; | ||
close mailCursor; | ||
SELECT CURTIME(); | ||
END $$ | ||
DELIMITER ; | ||
|
||
call attributeMailToInformation(); | ||
DROP PROCEDURE IF EXISTS attributeMailToInformation; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the review:
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
package org.zstack.core.encrypt; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.zstack.core.Platform; | ||
import org.zstack.core.cloudbus.CloudBus; | ||
import org.zstack.core.componentloader.PluginRegistry; | ||
import org.zstack.core.config.GlobalConfig; | ||
import org.zstack.core.config.GlobalConfigBeforeUpdateExtensionPoint; | ||
import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; | ||
import org.zstack.core.config.*; | ||
import org.zstack.core.convert.PasswordConverter; | ||
import org.zstack.core.db.DatabaseFacade; | ||
import org.zstack.core.db.SQLBatch; | ||
Comment on lines
3
to
11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 使用通配符导入 ( |
||
|
@@ -273,6 +272,123 @@ public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { | |
} | ||
} | ||
}); | ||
} | ||
|
||
protected void handleNewAddedEncryptEntity() { | ||
if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value())) { | ||
return; | ||
} | ||
|
||
List<EncryptEntityMetadataVO> metadataVOList = Q.New(EncryptEntityMetadataVO.class) | ||
.eq(EncryptEntityMetadataVO_.state, EncryptEntityState.NewAdded) | ||
.list(); | ||
|
||
new SQLBatch() { | ||
@Override | ||
protected void scripts() { | ||
for (EncryptEntityMetadataVO metadata : metadataVOList) { | ||
// do encrypt | ||
long count = SQL.New(String.format("select count(1) from %s", metadata.getEntityName()), Long.class).find(); | ||
metadata.setState(EncryptEntityState.Encrypting); | ||
metadata = dbf.updateAndRefresh(metadata); | ||
String className = metadata.getEntityName(); | ||
String fieldName = metadata.getColumnName(); | ||
sql(String.format("select uuid from %s", metadata.getEntityName()), String.class) | ||
.limit(1000) | ||
.paginate(count, (List<String> uuids) -> { | ||
for (String uuid : uuids) { | ||
String value = sql(String.format("select %s from %s where uuid = '%s'", fieldName, className, uuid)).find(); | ||
|
||
try { | ||
// If part of the data has been encrypted, first decrypt all the data before encrypting | ||
String decryptedString = decrypt(value); | ||
String encryptedString = encrypt(decryptedString); | ||
|
||
String sql = String.format("update %s set %s = :encrypted where uuid = :uuid", className, fieldName); | ||
|
||
Query query = dbf.getEntityManager().createQuery(sql); | ||
query.setParameter("encrypted", encryptedString); | ||
query.setParameter("uuid", uuid); | ||
query.executeUpdate(); | ||
} catch (Exception e) { | ||
logger.debug(String.format("encrypt error because : %s", e.getMessage())); | ||
} | ||
} | ||
|
||
}); | ||
metadata.setState(EncryptEntityState.Encrypted); | ||
dbf.updateAndRefresh(metadata); | ||
} | ||
} | ||
}.execute(); | ||
} | ||
|
||
private void collectEncryptEntityMetadata() { | ||
for (Field field : encryptedFields) { | ||
List<String> classNames = new ArrayList<>(); | ||
|
||
if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { | ||
classNames.add(field.getDeclaringClass().getSimpleName()); | ||
} else { | ||
classNames.addAll(BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() | ||
.filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) | ||
.map(Class::getSimpleName) | ||
.collect(Collectors.toList())); | ||
} | ||
|
||
for (String className : classNames) { | ||
createIfNotExists(className, field.getName()); | ||
} | ||
} | ||
} | ||
|
||
private void createIfNotExists(String entity, String column) { | ||
if (Q.New(EncryptEntityMetadataVO.class) | ||
.eq(EncryptEntityMetadataVO_.entityName, entity) | ||
.eq(EncryptEntityMetadataVO_.columnName, column) | ||
.isExists()) { | ||
return; | ||
} | ||
|
||
EncryptEntityMetadataVO metadataVO = new EncryptEntityMetadataVO(); | ||
metadataVO.setColumnName(column); | ||
metadataVO.setEntityName(entity); | ||
metadataVO.setState(EncryptEntityState.NewAdded); | ||
dbf.persist(metadataVO); | ||
} | ||
|
||
public void updateEncryptDataStateIfExists(String entity, String column, EncryptEntityState state) { | ||
String sql = String.format("update EncryptEntityMetadataVO set state = :state where columnName = :columnName and entityName = :entityName"); | ||
Query query = dbf.getEntityManager().createQuery(sql); | ||
query.setParameter("state", state); | ||
query.setParameter("entityName", entity); | ||
query.setParameter("columnName", column); | ||
query.executeUpdate(); | ||
} | ||
|
||
@Transactional | ||
public void removeConvertRecoverData() { | ||
if (Q.New(EncryptEntityMetadataVO.class) | ||
.isExists()) { | ||
return; | ||
} | ||
|
||
if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value())) { | ||
return; | ||
} | ||
|
||
decryptAllPassword(); | ||
encryptAllPassword(); | ||
} | ||
|
||
@Override | ||
public boolean start() { | ||
initEncryptDriver(); | ||
collectAllEncryptPassword(); | ||
installGlobalConfigUpdateHooks(); | ||
removeConvertRecoverData(); | ||
collectEncryptEntityMetadata(); | ||
handleNewAddedEncryptEntity(); | ||
|
||
return true; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with a brief code review:
In terms of potential bugs, I would recommend checking that all the data types match in the foreign key reference. Additionally, make sure that the "uuid" column is properly indexed for both tables.
Finally, it may be worth considering adding a timestamp column to the "IAM2VirtualIDInformationVO" table to keep track of when the rows were inserted or updated.