共计 5549 个字符,预计需要花费 14 分钟才能阅读完成。
1. 文件夹解密阐明
只有加密的文件夹才须要解密,同一用户在查看同一加密文件夹或者是外面的文件 / 文件夹,每次胜利校验明码后,再次查看同一加密文件夹或外面的文件 / 文件夹,不必输出明码,72 个小时后查看才须要输出明码;(除非有批改明码,如有批改明码,则须要从新输出,批改后第一次胜利验证明码后再开始计算 72 小时)。
注:校验是否 72 小时是在客户端实现
2. 文件夹解密过程
1)解密过程阐明
咱们在拜访加密的文件时:
先去依据 scopeToken 和 path 去本地数据库(sqlite)查找该文件先前是否有保留解密明码
如果存在的话,则会校验该条数据是否超过 72 小时,在没有超过 72 小时的状况下就拿这条数据的明码拜访接口 Get:/api/plugin/wangpan/folders/:path 校验明码是否正确:
正确的话进入文件夹详情,并更新该文件夹本地保留的明码和批改工夫;
谬误须要从新输出明码并拜访接口校验该明码是否正确;
校验数据是超过 72 小时的状况下,须要输出明码并拜访接口校验该明码是否正确:
在正确的状况下更新该文件夹本地保留的明码和批改工夫, 并插入该文件的明码缓存信息到数据库;
否则提醒用户明码谬误,从新输出;
2)次要代码实现
/**
* 文件
*/
public class HomeFragment extends BaseMVPDBFragment<FragmentHomeBinding, HomeContract.View, HomePresenter> implements HomeContract.View {
...
/**
* 初始化列表
*/
private void initRv() {homeFileAdapter = new HomeFileAdapter(1, true);
binding.rrv.setAdapter(homeFileAdapter)
.setOnRefreshAndLoadMoreListener(refreshLoadMoreListener);
homeFileAdapter.setOnItemClickListener((adapter, view, position) -> {mFileBean = homeFileAdapter.getItem(position);
if (mFileBean.getType() == 0 && homeFileAdapter.getSelectedSize() <= 0) { // 如果是文件夹,且没有处于编辑状态
if (mFileBean.getRead() == 1) { // 有读权限
if (mFileBean.getIs_encrypt() == 1) { // 加密文件
mPresenter.getFolderPwdByScopeTokenAndPath(Constant.scope_token, mFileBean.getPath());
} else { // 非加密文件
filePwd = "";
toFolderDetail(false);
}
} else { // 没有读权限
ToastUtil.show(UiUtil.getString(R.string.mine_without_read_permission));
}
}
});
...
}
...
/**
* 解密文件胜利
*/
@Override
public void decryptPwdSuccess() {if (inputPwdDialog != null && inputPwdDialog.isShowing()) {inputPwdDialog.dismiss();
}
if (mFolderPwd == null) {mFolderPwd = new FolderPassword(Constant.USER_ID, mFileBean.getPath(), filePwd, Constant.scope_token, TimeUtil.getCurrentTimeMillis());
mPresenter.insertFolderPwd(mFolderPwd);
} else {updateFolderPwd();
}
toFolderDetail(true);
}
/**
* 更新文件夹明码
*/
private void updateFolderPwd(){mFolderPwd.setPassword(filePwd);
mFolderPwd.setModifyTime(TimeUtil.getCurrentTimeMillis());
mPresenter.updateFolderPwd(mFolderPwd);
}
/**
* 解密文件失败
*
* @param errorCode
* @param msg
*/
@Override
public void decryptPwdFail(int errorCode, String msg) {if (errorCode == ErrorConstant.PWD_ERROR) { // 文件夹明码谬误
if (inputPwdDialog != null && !inputPwdDialog.isShowing()) {
filePwd = "";
updateFolderPwd();
inputPwdDialog.show(this);
}
}
}
/**
* 获取明码胜利
*
* @param folderPassword
*/
@Override
public void getFolderPwdByScopeTokenAndPathSuccess(FolderPassword folderPassword) {LogUtil.e("查问文件夹明码胜利");
if (folderPassword != null) {filePwd = folderPassword.getPassword();
long modifyTime = folderPassword.getModifyTime();
long distinct = TimeUtil.getCurrentTimeMillis() - modifyTime;
mFolderPwd = folderPassword;
if (TimeUtil.over72hour(distinct) || TextUtils.isEmpty(filePwd)) { // 超过 72 小时
showInputPwdDialog();} else {checkFilePwd();
}
} else {showInputPwdDialog();
}
}
/**
* 获取明码失败
*/
@Override
public void getFolderPwdByScopeTokenAndPathFail() {LogUtil.e("查问文件夹明码失败");
showInputPwdDialog();}
}
/**
* 文件的 presenter 层
*/
public class HomePresenter extends BasePresenter<HomeModel, HomeContract.View> implements HomeContract.Presenter {
...
/**
* 解密文件夹
* @param scopeToken
* @param path
* @param checkPwdRequest
*/
@Override
public void decryptFile(String scopeToken, String path, CheckPwdRequest checkPwdRequest) {executeObservable(mModel.decryptFile(scopeToken, path, checkPwdRequest), new RequestDataCallback<Object>(false) {
@Override
public void onSuccess(Object response) {super.onSuccess(response);
if (mView!=null){mView.decryptPwdSuccess();
}
}
@Override
public void onFailed(int errorCode, String errorMessage) {super.onFailed(errorCode, errorMessage);
if (mView!=null){mView.decryptPwdFail(errorCode, errorMessage);
}
}
});
}
/**
* 获取本地保留的文件夹明码
* @param scopeToken
* @param path
*/
@Override
public void getFolderPwdByScopeTokenAndPath(String scopeToken, String path) {executeDBObservable(mModel.getFolderPwdByScopeTokenAndPath(scopeToken, path), new RequestDataCallback<FolderPassword>() {
@Override
public void onSuccess(FolderPassword response) {super.onSuccess(response);
if (mView!=null){mView.getFolderPwdByScopeTokenAndPathSuccess(response);
}
}
@Override
public void onFailed() {super.onFailed();
if (mView!=null){mView.getFolderPwdByScopeTokenAndPathFail();
}
}
});
}
/**
* 插入文件夹明码
* @param folderPassword
*/
@Override
public void insertFolderPwd(FolderPassword folderPassword) {executeDBObservable(mModel.insertFolderPwd(folderPassword), new RequestDataCallback<Boolean>() {
@Override
public void onSuccess(Boolean response) {super.onSuccess(response);
if (mView!=null){if (response) {mView.insertFolderPwdSuccess(true);
}else {mView.insertFolderFail();
}
}
}
@Override
public void onFailed() {super.onFailed();
if (mView!=null){mView.insertFolderFail();
}
}
});
...
/**
* 校验文件夹明码是否正确
*/
private void checkFilePwd() {if (mFileBean != null) {if (TextUtils.isEmpty(filePwd)){ // 如果明码为空,则输出
inputPwdDialog.show(this);
}else { // 明码不为空,校验明码
CheckPwdRequest checkPwdRequest = new CheckPwdRequest(filePwd);
mPresenter.decryptFile(Constant.scope_token, mFileBean.getPath(), checkPwdRequest);
}
}
}
}
/**
* 批改文件夹明码
* @param folderPassword
*/
@Override
public void updateFolderPwd(FolderPassword folderPassword) {executeDBObservable(mModel.updateFolderPwd(folderPassword), new RequestDataCallback<Boolean>() {
@Override
public void onSuccess(Boolean response) {super.onSuccess(response);
if (mView!=null) {if (response) {mView.updateFolderPwdSuccess();
} else {mView.updateFolderPwdFail();
}
}
}
@Override
public void onFailed() {super.onFailed();
if (mView!=null){mView.updateFolderPwdFail();
}
}
});
}
}
3)数据库
智汀云盘存储文件夹明码相干信息的形式是应用 Android 本地数据库 SqLite,应用的数据库框架是 Greendao(greendao 的应用,请参照官网文档,这里不再赘述 greendao 的应用), 在查找文件夹明码时是通过文件夹的 path 和凭证查找的。上面是文件夹明码相干信息表的设计。
表名 | 形容 |
---|---|
id | 主键 id |
userId | 用户 id |
path | 文件夹门路 |
password | 文件夹明码 |
scopeToken | 凭证 |
modifyTime | 创立 / 批改工夫 |
以下是文件夹明码相干信息表的 model 类:
@Entity
public class FolderPassword {@Id(autoincrement = true)
private Long id; // 主键 id
private int userId; // 用户 id
private String path; // 文件夹门路
private String password; // 文件夹明码
private String scopeToken; // scopeToken
private Long modifyTime; // 创立 / 批改工夫
...
}
正文完