Пример #1
0
        /// <summary>
        /// Orchestrates common block reading procedures for the <see cref="WriteBlock"/> and
        /// <see cref="WriteBlockStreamed"/> methods.
        /// </summary>
        protected virtual void OrchestrateBlockWriting <T>(T dataBlock, Action <TTransfer, T> writerImplFunc) where T : class, IDataBlock
        {
            Ensure.ArgumentNotNull(dataBlock, "dataBlock");

            const FileSystemTask context  = FileSystemTask.DataBlockUploadRequest;
            TTransfer            transfer = GetCachedTransfer(dataBlock.TransferTokenId, true, context);

            lock (transfer.SyncRoot)
            {
                //make sure the transfer is active
                if (!transfer.Status.Is(TransferStatus.Starting, TransferStatus.Running, TransferStatus.Paused))
                {
                    string msg = String.Format("Transfer [{0}] is not active anymore - status is [{1}].", transfer.TransferId,
                                               transfer.Status);

                    if (transfer.AbortReason.HasValue)
                    {
                        msg += String.Format(" Transfer abort reason: [{0}].", transfer.AbortReason);
                    }

                    Auditor.AuditDeniedOperation(context, AuditEvent.UploadNoLongerActive, transfer.FileItem, msg);
                    throw new TransferStatusException(msg)
                          {
                              IsAudited = true, EventId = (int)AuditEvent.UploadNoLongerActive
                          };
                }

                if (!transfer.HasUploadStarted)
                {
                    if (transfer.FileItem.Exists)
                    {
                        //overwrite an existing file
                        DeleteExistingFileImpl(transfer);
                    }

                    InitializeFileUploadImpl(transfer);
                    transfer.HasUploadStarted = true;
                }

                //update status
                transfer.Status = TransferStatus.Running;

                ValidateBlockSizeAndSettings(transfer, dataBlock);

                //write the data to the file system
                writerImplFunc(transfer, dataBlock);

                //store copy of the uploaded block that doesn't contain any data
                transfer.RegisterBlock(DataBlockInfo.FromDataBlock(dataBlock));

                //audit uploaded block
                Auditor.AuditResourceOperation(context, AuditEvent.FileBlockUploaded, transfer.FileItem);

                //if we just read the last block, close implicitly
                if (dataBlock.IsLastBlock)
                {
                    CompleteTransfer(transfer.TransferId);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Orchestrates common block reading procedures for the <see cref="ReadBlock"/> and
        /// <see cref="ReadBlockStreamed"/> methods.
        /// </summary>
        protected virtual T OrchestrateBlockReading <T>(TTransfer transfer, long blockNumber,
                                                        Func <TTransfer, long, DataBlockInfo, T> readerImplFunc) where T : IDataBlock
        {
            const FileSystemTask context = FileSystemTask.DataBlockDownloadRequest;

            if (blockNumber < 0)
            {
                string msg = "Invalid block number [{0}] requested - block numbers cannot be negative.";
                msg = String.Format(msg, blockNumber);
                throw new DataBlockException(msg);
            }

            if (blockNumber >= transfer.Token.TotalBlockCount)
            {
                string msg = "Invalid block number [{0}] requested - the total number of blocks is [{1}].";
                msg = String.Format(msg, blockNumber, transfer.Token.TotalBlockCount);
                throw new DataBlockException(msg);
            }

            //make sure the file still exists
            if (!transfer.FileItem.Exists)
            {
                Auditor.AuditRequestedFileNotFound(transfer.FileItem, context);

                string msg = "Resource [{0}] of transfer [{1}] was not found.";
                msg = String.Format(msg, transfer.Token.ResourceName, transfer.TransferId);
                throw new VirtualResourceNotFoundException(msg)
                      {
                          IsAudited = true
                      };
            }

            lock (transfer.SyncRoot)
            {
                //make sure the transfer is active
                if (!transfer.Status.Is(TransferStatus.Starting, TransferStatus.Running, TransferStatus.Paused))
                {
                    string msg = String.Format("Transfer [{0}] is not active anymore - status is [{1}].", transfer.TransferId,
                                               transfer.Status);

                    if (transfer.AbortReason.HasValue)
                    {
                        msg += String.Format(" Transfer abort reason: [{0}].", transfer.AbortReason);
                    }

                    Auditor.AuditDeniedOperation(context, AuditEvent.DownloadNoLongerActive, transfer.FileItem, msg);
                    throw new TransferStatusException(msg)
                          {
                              IsAudited = true, EventId = (int)AuditEvent.DownloadNoLongerActive
                          };
                }

                //check whether we already transferred this block once
                DataBlockInfo transferredBlock = transfer.TryGetTransferredBlock(blockNumber);

                T dataBlock = readerImplFunc(transfer, blockNumber, transferredBlock);

                //update status
                transfer.Status = TransferStatus.Running;

                //store copy of the downloaded block that doesn't contain any data
                transfer.RegisterBlock(DataBlockInfo.FromDataBlock(dataBlock));

                //audit download
                Auditor.AuditTransferOperation(context, AuditEvent.FileBlockDownloaded, transfer.TransferId, transfer.FileItem);

                return(dataBlock);
            }
        }
Пример #3
0
        private TTransfer InitTransferImpl(string submittedResourceFilePath, bool overwrite, long resourceLength, string contentType)
        {
            const FileSystemTask context = FileSystemTask.UploadTokenRequest;

            //validate maximum file size
            var maxFileSize = GetMaxFileUploadSize();

            if (maxFileSize.HasValue && maxFileSize < resourceLength)
            {
                string msg = "Upload for file [{0}] denied: Resource length of [{1}] is above the maximum upload limit of [{2}] bytes.";
                msg = String.Format(msg, submittedResourceFilePath, resourceLength, maxFileSize.Value);
                throw new ResourceAccessException(msg);
            }

            //of course, the length cannot be negative
            if (resourceLength < 0)
            {
                string msg = "Upload for file [{0}] denied: Resource length cannot be negative [{1}].";
                msg = String.Format(msg, submittedResourceFilePath, resourceLength);
                throw new ResourceAccessException(msg);
            }


            TFile fileItem = CreateFileItemImpl(submittedResourceFilePath, false, context);

            if (fileItem.Exists && !overwrite)
            {
                Auditor.AuditDeniedOperation(context, AuditEvent.FileAlreadyExists, fileItem);

                string msg = String.Format("Cannot upload file [{0}] without overwriting existing data - a file already exists at this location.", submittedResourceFilePath);
                throw new ResourceOverwriteException(msg)
                      {
                          IsAudited = true
                      };
            }

            //get authorization
            TFolder parentFolder = GetParentFolder(fileItem, context);

            //validate file system specific restrictions
            VerifyCanUploadFileToFileSystemLocation(submittedResourceFilePath, parentFolder, fileItem);

            //get parent folder and check whether files can be added
            FolderClaims folderClaims = GetParentFolderClaims(fileItem, parentFolder);

            if (!folderClaims.AllowAddFiles)
            {
                //deny adding a file to that folder
                Auditor.AuditDeniedOperation(context, AuditEvent.CreateFileDenied, fileItem);

                string msg = "Cannot create file at [{0}] - adding files to the folder is not permitted.";
                msg = String.Format(msg, submittedResourceFilePath);
                throw new ResourceAccessException(msg)
                      {
                          IsAudited = true
                      };
            }


            //only overwrite a file if explicitly requested
            FileClaims claims = GetFileClaims(fileItem);

            if (fileItem.Exists)
            {
                if (!claims.AllowOverwrite)
                {
                    Auditor.AuditDeniedOperation(context, AuditEvent.FileDataOverwriteDenied, fileItem);

                    string msg = "Overwriting file [{0}] was denied due to missing permission.";
                    msg = String.Format(msg, submittedResourceFilePath);
                    throw new ResourceOverwriteException(msg)
                          {
                              IsAudited = true
                          };
                }
            }


            //try to get lock
            ResourceLockGuard writeLock = LockResourceForUpload(fileItem);

            if (writeLock != null && !writeLock.IsLockEnabled)
            {
                Auditor.AuditDeniedOperation(context, AuditEvent.FileReadLockDenied, fileItem);

                string msg = "The file [{0}] is currently locked and cannot be accessed.";
                msg = String.Format(msg, submittedResourceFilePath);
                throw new ResourceLockedException(msg)
                      {
                          IsAudited = true
                      };
            }

            //create upload token
            UploadToken token = CreateUploadToken(submittedResourceFilePath, fileItem, resourceLength, contentType);

            //create expiration job if we have an expiration time
            Job <UploadToken> job = null;

            if (token.ExpirationTime.HasValue)
            {
                job = ScheduleExpiration(token);
            }

            //create and cache transfer instance
            TTransfer transfer = CreateTransfer(submittedResourceFilePath, fileItem, parentFolder, token, claims, writeLock, job);

            TransferStore.AddTransfer(transfer);

            Auditor.AuditResourceOperation(context, AuditEvent.UploadTokenIssued, fileItem);
            return(transfer);
        }
Пример #4
0
        private TTransfer InitTransferImpl(string submittedResourceFilePath, int?clientMaxBlockSize, bool includeFileHash)
        {
            const FileSystemTask context = FileSystemTask.DownloadTokenRequest;
            TFile fileItem = CreateFileItemImpl(submittedResourceFilePath, false, context);

            if (!fileItem.Exists)
            {
                Auditor.AuditRequestedFileNotFound(fileItem, context);

                string msg = String.Format("Resource [{0}] not found.", submittedResourceFilePath);
                throw new VirtualResourceNotFoundException(msg)
                      {
                          IsAudited = true
                      };
            }

            //get authorization
            FileClaims claims = GetFileClaims(fileItem);

            if (!claims.AllowReadData)
            {
                Auditor.AuditDeniedOperation(context, AuditEvent.FileDataDownloadDenied, fileItem);

                string msg = "Read request for file [{0}] was denied - you are not authorized to read the resource.";
                msg = String.Format(msg, submittedResourceFilePath);
                throw new ResourceAccessException(msg)
                      {
                          IsAudited = true
                      };
            }

            //try to get lock
            ResourceLockGuard readLock = LockResourceForDownload(fileItem, claims);

            if (readLock != null && !readLock.IsLockEnabled)
            {
                Auditor.AuditDeniedOperation(context, AuditEvent.FileReadLockDenied, fileItem);

                string msg = "The requested file [{0}] is currently locked and thus cannot be accessed.";
                msg = String.Format(msg, submittedResourceFilePath);
                throw new ResourceLockedException(msg)
                      {
                          IsAudited = true
                      };
            }

            //create download token
            DownloadToken token = CreateDownloadToken(submittedResourceFilePath, fileItem, clientMaxBlockSize, includeFileHash);

            //create expiration job if we have an expiration time
            Job <DownloadToken> job = null;

            if (token.ExpirationTime.HasValue)
            {
                job = ScheduleExpiration(token);
            }

            //create transfer instance
            TTransfer transfer = CreateTransfer(submittedResourceFilePath, fileItem, token, claims, readLock, job);

            //cache transfer
            TransferStore.AddTransfer(transfer);

            //audit issued token
            Auditor.AuditResourceOperation(context, AuditEvent.DownloadTokenIssued, fileItem);

            return(transfer);
        }