Adopt API to update file if already uploaded
This commit is contained in:
parent
58d4635bb5
commit
51f083d290
2 changed files with 137 additions and 50 deletions
|
@ -38,7 +38,7 @@ EncryptionResult chachaEncryptFile(Map<String, dynamic> args) {
|
|||
logger.info("Encrypting file of size " + sourceFileLength.toString());
|
||||
|
||||
final inputFile = sourceFile.openSync(mode: io.FileMode.read);
|
||||
final key = Sodium.cryptoSecretstreamXchacha20poly1305Keygen();
|
||||
final key = args["key"] ?? Sodium.cryptoSecretstreamXchacha20poly1305Keygen();
|
||||
final initPushResult =
|
||||
Sodium.cryptoSecretstreamXchacha20poly1305InitPush(key);
|
||||
var bytesRead = 0;
|
||||
|
@ -155,11 +155,13 @@ class CryptoUtil {
|
|||
|
||||
static Future<EncryptionResult> encryptFile(
|
||||
String sourceFilePath,
|
||||
String destinationFilePath,
|
||||
) {
|
||||
String destinationFilePath, {
|
||||
Uint8List key,
|
||||
}) {
|
||||
final args = Map<String, dynamic>();
|
||||
args["sourceFilePath"] = sourceFilePath;
|
||||
args["destinationFilePath"] = destinationFilePath;
|
||||
args["key"] = key;
|
||||
return Computer().compute(chachaEncryptFile, param: args);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ import 'dart:convert';
|
|||
import 'dart:io' as io;
|
||||
import 'package:connectivity/connectivity.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
import 'package:flutter_sodium/flutter_sodium.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/core/network.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/models/encryption_result.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/models/location.dart';
|
||||
import 'package:photos/models/upload_url.dart';
|
||||
|
@ -152,13 +152,26 @@ class FileUploader {
|
|||
final encryptedThumbnailPath =
|
||||
tempDirectory + file.generatedID.toString() + "_thumbnail.encrypted";
|
||||
final sourceFile = (await (await file.getAsset()).originFile);
|
||||
|
||||
try {
|
||||
var key;
|
||||
var isAlreadyUploadedFile = file.uploadedFileID != null;
|
||||
if (isAlreadyUploadedFile) {
|
||||
key = decryptFileKey(file);
|
||||
} else {
|
||||
key = null;
|
||||
}
|
||||
|
||||
if (io.File(encryptedFilePath).existsSync()) {
|
||||
io.File(encryptedFilePath).deleteSync();
|
||||
}
|
||||
final encryptedFile = io.File(encryptedFilePath);
|
||||
final fileAttributes =
|
||||
await CryptoUtil.encryptFile(sourceFile.path, encryptedFilePath);
|
||||
|
||||
final fileAttributes = await CryptoUtil.encryptFile(
|
||||
sourceFile.path,
|
||||
encryptedFilePath,
|
||||
key: key,
|
||||
);
|
||||
|
||||
var thumbnailData = (await (await file.getAsset()).thumbDataWithSize(
|
||||
THUMBNAIL_LARGE_SIZE,
|
||||
|
@ -201,15 +214,6 @@ class FileUploader {
|
|||
|
||||
final encryptedMetadataData = CryptoUtil.encryptChaCha(
|
||||
utf8.encode(jsonEncode(file.getMetadata())), fileAttributes.key);
|
||||
|
||||
final encryptedFileKeyData = CryptoUtil.encryptSync(
|
||||
fileAttributes.key,
|
||||
CollectionsService.instance.getCollectionKey(collectionID),
|
||||
);
|
||||
|
||||
final encryptedKey =
|
||||
Sodium.bin2base64(encryptedFileKeyData.encryptedData);
|
||||
final keyDecryptionNonce = Sodium.bin2base64(encryptedFileKeyData.nonce);
|
||||
final fileDecryptionHeader = Sodium.bin2base64(fileAttributes.header);
|
||||
final thumbnailDecryptionHeader =
|
||||
Sodium.bin2base64(encryptedThumbnailData.header);
|
||||
|
@ -217,41 +221,29 @@ class FileUploader {
|
|||
Sodium.bin2base64(encryptedMetadataData.encryptedData);
|
||||
final metadataDecryptionHeader =
|
||||
Sodium.bin2base64(encryptedMetadataData.header);
|
||||
|
||||
final request = {
|
||||
"collectionID": collectionID,
|
||||
"encryptedKey": encryptedKey,
|
||||
"keyDecryptionNonce": keyDecryptionNonce,
|
||||
"file": {
|
||||
"objectKey": fileObjectKey,
|
||||
"decryptionHeader": fileDecryptionHeader,
|
||||
},
|
||||
"thumbnail": {
|
||||
"objectKey": thumbnailObjectKey,
|
||||
"decryptionHeader": thumbnailDecryptionHeader,
|
||||
},
|
||||
"metadata": {
|
||||
"encryptedData": encryptedMetadata,
|
||||
"decryptionHeader": metadataDecryptionHeader,
|
||||
}
|
||||
};
|
||||
final response = await _dio.post(
|
||||
Configuration.instance.getHttpEndpoint() + "/files",
|
||||
options: Options(
|
||||
headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
||||
data: request,
|
||||
);
|
||||
final data = response.data;
|
||||
file.uploadedFileID = data["id"];
|
||||
file.collectionID = collectionID;
|
||||
file.updationTime = data["updationTime"];
|
||||
file.ownerID = data["ownerID"];
|
||||
file.encryptedKey = encryptedKey;
|
||||
file.keyDecryptionNonce = keyDecryptionNonce;
|
||||
file.fileDecryptionHeader = fileDecryptionHeader;
|
||||
file.thumbnailDecryptionHeader = thumbnailDecryptionHeader;
|
||||
file.metadataDecryptionHeader = metadataDecryptionHeader;
|
||||
return file;
|
||||
if (isAlreadyUploadedFile) {
|
||||
return await _updateFile(
|
||||
file,
|
||||
fileObjectKey,
|
||||
fileDecryptionHeader,
|
||||
thumbnailObjectKey,
|
||||
thumbnailDecryptionHeader,
|
||||
encryptedMetadata,
|
||||
metadataDecryptionHeader,
|
||||
);
|
||||
} else {
|
||||
return await _uploadFile(
|
||||
file,
|
||||
collectionID,
|
||||
fileAttributes,
|
||||
fileObjectKey,
|
||||
fileDecryptionHeader,
|
||||
thumbnailObjectKey,
|
||||
thumbnailDecryptionHeader,
|
||||
encryptedMetadata,
|
||||
metadataDecryptionHeader,
|
||||
);
|
||||
}
|
||||
} catch (e, s) {
|
||||
_logger.severe(
|
||||
"File upload failed for " + file.generatedID.toString(), e, s);
|
||||
|
@ -269,6 +261,99 @@ class FileUploader {
|
|||
}
|
||||
}
|
||||
|
||||
Future<File> _uploadFile(
|
||||
File file,
|
||||
int collectionID,
|
||||
EncryptionResult fileAttributes,
|
||||
String fileObjectKey,
|
||||
String fileDecryptionHeader,
|
||||
String thumbnailObjectKey,
|
||||
String thumbnailDecryptionHeader,
|
||||
String encryptedMetadata,
|
||||
String metadataDecryptionHeader,
|
||||
) async {
|
||||
final encryptedFileKeyData = CryptoUtil.encryptSync(
|
||||
fileAttributes.key,
|
||||
CollectionsService.instance.getCollectionKey(collectionID),
|
||||
);
|
||||
final encryptedKey = Sodium.bin2base64(encryptedFileKeyData.encryptedData);
|
||||
final keyDecryptionNonce = Sodium.bin2base64(encryptedFileKeyData.nonce);
|
||||
final request = {
|
||||
"collectionID": collectionID,
|
||||
"encryptedKey": encryptedKey,
|
||||
"keyDecryptionNonce": keyDecryptionNonce,
|
||||
"file": {
|
||||
"objectKey": fileObjectKey,
|
||||
"decryptionHeader": fileDecryptionHeader,
|
||||
},
|
||||
"thumbnail": {
|
||||
"objectKey": thumbnailObjectKey,
|
||||
"decryptionHeader": thumbnailDecryptionHeader,
|
||||
},
|
||||
"metadata": {
|
||||
"encryptedData": encryptedMetadata,
|
||||
"decryptionHeader": metadataDecryptionHeader,
|
||||
}
|
||||
};
|
||||
final response = await _dio.post(
|
||||
Configuration.instance.getHttpEndpoint() + "/files",
|
||||
options:
|
||||
Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
||||
data: request,
|
||||
);
|
||||
final data = response.data;
|
||||
file.uploadedFileID = data["id"];
|
||||
file.collectionID = collectionID;
|
||||
file.updationTime = data["updationTime"];
|
||||
file.ownerID = data["ownerID"];
|
||||
file.encryptedKey = encryptedKey;
|
||||
file.keyDecryptionNonce = keyDecryptionNonce;
|
||||
file.fileDecryptionHeader = fileDecryptionHeader;
|
||||
file.thumbnailDecryptionHeader = thumbnailDecryptionHeader;
|
||||
file.metadataDecryptionHeader = metadataDecryptionHeader;
|
||||
return file;
|
||||
}
|
||||
|
||||
Future<File> _updateFile(
|
||||
File file,
|
||||
String fileObjectKey,
|
||||
String fileDecryptionHeader,
|
||||
String thumbnailObjectKey,
|
||||
String thumbnailDecryptionHeader,
|
||||
String encryptedMetadata,
|
||||
String metadataDecryptionHeader,
|
||||
) async {
|
||||
final request = {
|
||||
"id": file.uploadedFileID,
|
||||
"file": {
|
||||
"objectKey": fileObjectKey,
|
||||
"decryptionHeader": fileDecryptionHeader,
|
||||
},
|
||||
"thumbnail": {
|
||||
"objectKey": thumbnailObjectKey,
|
||||
"decryptionHeader": thumbnailDecryptionHeader,
|
||||
},
|
||||
"metadata": {
|
||||
"encryptedData": encryptedMetadata,
|
||||
"decryptionHeader": metadataDecryptionHeader,
|
||||
}
|
||||
};
|
||||
final response = await _dio.post(
|
||||
Configuration.instance.getHttpEndpoint() + "/files",
|
||||
options:
|
||||
Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
||||
data: request,
|
||||
);
|
||||
final data = response.data;
|
||||
file.uploadedFileID = data["id"];
|
||||
file.updationTime = data["updationTime"];
|
||||
file.ownerID = data["ownerID"];
|
||||
file.fileDecryptionHeader = fileDecryptionHeader;
|
||||
file.thumbnailDecryptionHeader = thumbnailDecryptionHeader;
|
||||
file.metadataDecryptionHeader = metadataDecryptionHeader;
|
||||
return file;
|
||||
}
|
||||
|
||||
Future<UploadURL> _getUploadURL() async {
|
||||
if (_uploadURLs.isEmpty) {
|
||||
await _fetchUploadURLs();
|
||||
|
|
Loading…
Add table
Reference in a new issue