Exemple #1
0
        public async Task <(string attachmentId, string uploadUrl)> CreateAttachmentForDelayedUploadAsync(Cipher cipher,
                                                                                                          AttachmentRequestModel request, Guid savingUserId)
        {
            await ValidateCipherEditForAttachmentAsync(cipher, savingUserId, request.AdminRequest, request.FileSize);

            var attachmentId = Utilities.CoreHelpers.SecureRandomString(32, upper: false, special: false);
            var data         = new CipherAttachment.MetaData
            {
                AttachmentId = attachmentId,
                FileName     = request.FileName,
                Key          = request.Key,
                Size         = request.FileSize,
                Validated    = false,
            };

            var uploadUrl = await _attachmentStorageService.GetAttachmentUploadUrlAsync(cipher, data);

            await _cipherRepository.UpdateAttachmentAsync(new CipherAttachment
            {
                Id             = cipher.Id,
                UserId         = cipher.UserId,
                OrganizationId = cipher.OrganizationId,
                AttachmentId   = attachmentId,
                AttachmentData = JsonConvert.SerializeObject(data)
            });

            cipher.AddAttachment(attachmentId, data);
            await _pushService.PushSyncCipherUpdateAsync(cipher, null);

            return(attachmentId, uploadUrl);
        }
        public async Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, string key,
                                                long requestLength, Guid savingUserId, bool orgAdmin = false)
        {
            if (!orgAdmin && !(await UserCanEditAsync(cipher, savingUserId)))
            {
                throw new BadRequestException("You do not have permissions to edit this.");
            }

            if (requestLength < 1)
            {
                throw new BadRequestException("No data to attach.");
            }

            var storageBytesRemaining = 10240L;

            if (storageBytesRemaining < requestLength)
            {
                throw new BadRequestException("Not enough storage available.");
            }

            var attachmentId = Utilities.CoreHelpers.SecureRandomString(32, upper: false, special: false);
            await _attachmentStorageService.UploadNewAttachmentAsync(stream, cipher, attachmentId);

            try
            {
                var data = new CipherAttachment.MetaData
                {
                    FileName = fileName,
                    Key      = key,
                    Size     = stream.Length
                };

                var attachment = new CipherAttachment
                {
                    Id             = cipher.Id,
                    UserId         = cipher.UserId,
                    OrganizationId = cipher.OrganizationId,
                    AttachmentId   = attachmentId,
                    AttachmentData = JsonConvert.SerializeObject(data)
                };

                await _cipherRepository.UpdateAttachmentAsync(attachment);

                await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_AttachmentCreated);

                cipher.AddAttachment(attachmentId, data);
            }
            catch
            {
                // Clean up since this is not transactional
                await _attachmentStorageService.DeleteAttachmentAsync(cipher.Id, attachmentId);

                throw;
            }

            // push
            await _pushService.PushSyncCipherUpdateAsync(cipher, null);
        }
Exemple #3
0
        public async Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, string key,
                                                long requestLength, Guid savingUserId, bool orgAdmin = false)
        {
            await ValidateCipherEditForAttachmentAsync(cipher, savingUserId, orgAdmin, requestLength);

            var attachmentId = Utilities.CoreHelpers.SecureRandomString(32, upper: false, special: false);
            var data         = new CipherAttachment.MetaData
            {
                AttachmentId = attachmentId,
                FileName     = fileName,
                Key          = key,
            };

            await _attachmentStorageService.UploadNewAttachmentAsync(stream, cipher, data);

            // Must read stream length after it has been saved, otherwise it's 0
            data.Size = stream.Length;

            try
            {
                var attachment = new CipherAttachment
                {
                    Id             = cipher.Id,
                    UserId         = cipher.UserId,
                    OrganizationId = cipher.OrganizationId,
                    AttachmentId   = attachmentId,
                    AttachmentData = JsonConvert.SerializeObject(data)
                };

                await _cipherRepository.UpdateAttachmentAsync(attachment);

                await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_AttachmentCreated);

                cipher.AddAttachment(attachmentId, data);

                if (!await ValidateCipherAttachmentFile(cipher, data))
                {
                    throw new Exception("Content-Length does not match uploaded file size");
                }
            }
            catch
            {
                // Clean up since this is not transactional
                await _attachmentStorageService.DeleteAttachmentAsync(cipher.Id, data);

                throw;
            }

            // push
            await _pushService.PushSyncCipherUpdateAsync(cipher, null);
        }
Exemple #4
0
        public async Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, long requestLength,
                                                Guid savingUserId, bool orgAdmin = false)
        {
            if (!orgAdmin && !(await UserCanEditAsync(cipher, savingUserId)))
            {
                throw new BadRequestException("You do not have permissions to edit this.");
            }

            if (requestLength < 1)
            {
                throw new BadRequestException("No data to attach.");
            }

            var storageBytesRemaining = 0L;

            if (cipher.UserId.HasValue)
            {
                var user = await _userRepository.GetByIdAsync(cipher.UserId.Value);

                if (!(await _userService.CanAccessPremium(user)))
                {
                    throw new BadRequestException("You must have premium status to use attachments.");
                }

                if (user.Premium)
                {
                    storageBytesRemaining = user.StorageBytesRemaining();
                }
                else
                {
                    // Users that get access to file storage/premium from their organization get the default
                    // 1 GB max storage.
                    storageBytesRemaining = user.StorageBytesRemaining(
                        _globalSettings.SelfHosted ? (short)1024 : (short)1);
                }
            }
            else if (cipher.OrganizationId.HasValue)
            {
                var org = await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value);

                if (!org.MaxStorageGb.HasValue)
                {
                    throw new BadRequestException("This organization cannot use attachments.");
                }

                storageBytesRemaining = org.StorageBytesRemaining();
            }

            if (storageBytesRemaining < requestLength)
            {
                throw new BadRequestException("Not enough storage available.");
            }

            var attachmentId = Utilities.CoreHelpers.SecureRandomString(32, upper: false, special: false);
            await _attachmentStorageService.UploadNewAttachmentAsync(stream, cipher, attachmentId);

            try
            {
                var data = new CipherAttachment.MetaData
                {
                    FileName = fileName,
                    Size     = stream.Length
                };

                var attachment = new CipherAttachment
                {
                    Id             = cipher.Id,
                    UserId         = cipher.UserId,
                    OrganizationId = cipher.OrganizationId,
                    AttachmentId   = attachmentId,
                    AttachmentData = JsonConvert.SerializeObject(data)
                };

                await _cipherRepository.UpdateAttachmentAsync(attachment);

                await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_AttachmentCreated);

                cipher.AddAttachment(attachmentId, data);
            }
            catch
            {
                // Clean up since this is not transactional
                await _attachmentStorageService.DeleteAttachmentAsync(cipher.Id, attachmentId);

                throw;
            }

            // push
            await _pushService.PushSyncCipherUpdateAsync(cipher, null);
        }