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类:
@Entitypublic 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; // 创立/批改工夫 ... }