123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import 'dart:convert';
- import 'dart:io' as io;
- import 'package:dio/dio.dart';
- import 'package:logging/logging.dart';
- import 'package:photos/core/configuration.dart';
- import 'package:photos/core/constants.dart';
- import 'package:photos/models/decryption_params.dart';
- import 'package:photos/models/file.dart';
- import 'package:photos/models/upload_url.dart';
- import 'package:photos/utils/crypto_util.dart';
- import 'package:photos/utils/file_name_util.dart';
- import 'package:photos/utils/file_util.dart';
- class FileUploader {
- final _logger = Logger("FileUploader");
- final _dio = Dio();
- Future<UploadURL> getUploadURL() {
- return Dio()
- .get(
- Configuration.instance.getHttpEndpoint() +
- "/encrypted-files/upload-url",
- options: Options(
- headers: {"X-Auth-Token": Configuration.instance.getToken()}),
- )
- .then((response) => UploadURL.fromMap(response.data));
- }
- Future<String> putFile(UploadURL uploadURL, io.File file) async {
- _logger.info("Putting file to " + uploadURL.url);
- return Dio()
- .put(uploadURL.url,
- data: file.openRead(),
- options: Options(headers: {
- Headers.contentLengthHeader: await file.length(),
- }))
- .catchError((e) {
- _logger.severe(e);
- }).then((value) {
- return uploadURL.objectKey;
- });
- }
- Future<File> encryptAndUploadFile(File file) async {
- _logger.info("Uploading " + file.toString());
- final encryptedFileName = file.generatedID.toString() + ".encrypted";
- final tempDirectory = Configuration.instance.getTempDirectory();
- final encryptedFilePath = tempDirectory + encryptedFileName;
- final sourceFile = (await (await file.getAsset()).originFile);
- final encryptedFile = io.File(encryptedFilePath);
- final fileAttributes =
- await CryptoUtil.chachaEncrypt(sourceFile, encryptedFile);
- final fileUploadURL = await getUploadURL();
- String fileObjectKey = await putFile(fileUploadURL, encryptedFile);
- final encryptedFileKey = await CryptoUtil.encrypt(
- fileAttributes.key.bytes,
- key: Configuration.instance.getKey(),
- );
- final fileDecryptionParams = DecryptionParams(
- encryptedKey: encryptedFileKey.encryptedData.base64,
- keyDecryptionNonce: encryptedFileKey.nonce.base64,
- header: fileAttributes.header.base64,
- );
- final thumbnailData = (await (await file.getAsset()).thumbDataWithSize(
- THUMBNAIL_LARGE_SIZE,
- THUMBNAIL_LARGE_SIZE,
- quality: 50,
- ));
- final encryptedThumbnailName =
- file.generatedID.toString() + "_thumbnail.encrypted";
- final encryptedThumbnailPath = tempDirectory + encryptedThumbnailName;
- final encryptedThumbnail = await CryptoUtil.encrypt(thumbnailData);
- io.File(encryptedThumbnailPath)
- .writeAsBytesSync(encryptedThumbnail.encryptedData.bytes);
- final thumbnailUploadURL = await getUploadURL();
- String thumbnailObjectKey =
- await putFile(thumbnailUploadURL, io.File(encryptedThumbnailPath));
- final encryptedThumbnailKey = await CryptoUtil.encrypt(
- encryptedThumbnail.key.bytes,
- key: Configuration.instance.getKey(),
- );
- final thumbnailDecryptionParams = DecryptionParams(
- encryptedKey: encryptedThumbnailKey.encryptedData.base64,
- keyDecryptionNonce: encryptedThumbnailKey.nonce.base64,
- nonce: encryptedThumbnail.nonce.base64,
- );
- final metadata = jsonEncode(file.getMetadata());
- final encryptedMetadata = await CryptoUtil.encrypt(utf8.encode(metadata));
- final encryptedMetadataKey = await CryptoUtil.encrypt(
- encryptedMetadata.key.bytes,
- key: Configuration.instance.getKey(),
- );
- final metadataDecryptionParams = DecryptionParams(
- encryptedKey: encryptedMetadataKey.encryptedData.base64,
- keyDecryptionNonce: encryptedMetadataKey.nonce.base64,
- nonce: encryptedMetadata.nonce.base64,
- );
- final data = {
- "file": {
- "objectKey": fileObjectKey,
- "decryptionParams": fileDecryptionParams.toMap(),
- },
- "thumbnail": {
- "objectKey": thumbnailObjectKey,
- "decryptionParams": thumbnailDecryptionParams,
- },
- "metadata": {
- "encryptedData": encryptedMetadata.encryptedData.base64,
- "decryptionParams": metadataDecryptionParams,
- }
- };
- return _dio
- .post(
- Configuration.instance.getHttpEndpoint() + "/encrypted-files",
- options:
- Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
- data: data,
- )
- .then((response) {
- encryptedFile.deleteSync();
- io.File(encryptedThumbnailPath).deleteSync();
- final data = response.data;
- file.uploadedFileID = data["id"];
- file.updationTime = data["updationTime"];
- file.ownerID = data["ownerID"];
- file.fileDecryptionParams = fileDecryptionParams;
- file.thumbnailDecryptionParams = thumbnailDecryptionParams;
- file.metadataDecryptionParams = metadataDecryptionParams;
- return file;
- });
- }
- Future<File> uploadFile(File localPhoto) async {
- final title = getJPGFileNameForHEIC(localPhoto);
- final formData = FormData.fromMap({
- "file": MultipartFile.fromBytes(await getBytesFromDisk(localPhoto),
- filename: title),
- "deviceFileID": localPhoto.localID,
- "deviceFolder": localPhoto.deviceFolder,
- "title": title,
- "creationTime": localPhoto.creationTime,
- "modificationTime": localPhoto.modificationTime,
- });
- return _dio
- .post(
- Configuration.instance.getHttpEndpoint() + "/files",
- options:
- Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
- data: formData,
- )
- .then((response) {
- return File.fromJson(response.data);
- });
- }
- }
|