import StorageErrorFactory from "../errors/StorageErrorFactory" ; import { ModifiedAccessConditions , SequenceNumberAccessConditions } from "../generated/artifacts/models" ; import Context from "../generated/Context" ; import { BlobModel , ContainerModel } from "../persistence/IBlobMetadataStore" ; import ConditionalHeadersAdapter from "./ConditionalHeadersAdapter" ; import ConditionResourceAdapter from "./ConditionResourceAdapter" ; import { IConditionalHeaders } from "./IConditionalHeaders" ; import { IConditionalHeadersValidator } from "./IConditionalHeadersValidator" ; import IConditionResource from "./IConditionResource" ; export function validateSequenceNumberWriteConditions ( context , conditionalHeaders ? , model ? ) { if ( ! conditionalHeaders || ! model ) { return ; } if ( ! model . properties || model . properties . blobSequenceNumber === undefined ) { throw Error ( `validateSequenceNumberWriteConditions() Invalid blob model, blobSequenceNumber is not specified.` ) ; } if ( conditionalHeaders . ifSequenceNumberLessThanOrEqualTo !== undefined && conditionalHeaders . ifSequenceNumberLessThanOrEqualTo < model . properties . blobSequenceNumber ) { throw StorageErrorFactory . getSequenceNumberConditionNotMet ( context . contextId ! ) ; } if ( conditionalHeaders . ifSequenceNumberLessThan !== undefined && conditionalHeaders . ifSequenceNumberLessThan <= model . properties . blobSequenceNumber ) { throw StorageErrorFactory . getSequenceNumberConditionNotMet ( context . contextId ! ) ; } if ( conditionalHeaders . ifSequenceNumberEqualTo !== undefined && conditionalHeaders . ifSequenceNumberEqualTo !== model . properties . blobSequenceNumber ) { throw StorageErrorFactory . getSequenceNumberConditionNotMet ( context . contextId ! ) ; } } export function validateWriteConditions ( context , conditionalHeaders ? , model ? ) { new WriteConditionalHeadersValidator ( ) . validate ( context , new ConditionalHeadersAdapter ( context , conditionalHeaders ) , new ConditionResourceAdapter ( model ) ) ; } export default class WriteConditionalHeadersValidator implements IConditionalHeadersValidator { link param context param conditionalHeaders param resource public validate ( context , conditionalHeaders , resource ) { this . validateCombinations ( context , conditionalHeaders ) ; if ( ! resource . exist ) { if ( conditionalHeaders . ifNoneMatch && conditionalHeaders . ifNoneMatch . length > 0 ) { return ; } if ( conditionalHeaders . ifMatch && conditionalHeaders . ifMatch . length > 0 ) { if ( conditionalHeaders . ifMatch [ 0 ] !== "*" ) { throw StorageErrorFactory . getConditionNotMet ( context . contextId ! ) ; } return ; } if ( conditionalHeaders . ifModifiedSince ) { return ; } if ( conditionalHeaders . ifUnmodifiedSince ) { return ; } } else { if ( conditionalHeaders . ifNoneMatch && conditionalHeaders . ifNoneMatch . length > 0 ) { if ( conditionalHeaders . ifNoneMatch [ 0 ] === "*" ) { return ; } if ( conditionalHeaders . ifNoneMatch [ 0 ] === resource . etag ) { throw StorageErrorFactory . getConditionNotMet ( context . contextId ! ) ; } return ; } if ( conditionalHeaders . ifMatch && conditionalHeaders . ifMatch . length > 0 ) { if ( conditionalHeaders . ifMatch [ 0 ] !== "*" && conditionalHeaders . ifMatch [ 0 ] !== resource . etag ) { throw StorageErrorFactory . getConditionNotMet ( context . contextId ! ) ; } return ; } if ( conditionalHeaders . ifModifiedSince ) { if ( resource . lastModified <= conditionalHeaders . ifModifiedSince ) { throw StorageErrorFactory . getConditionNotMet ( context . contextId ! ) ; } return ; } if ( conditionalHeaders . ifUnmodifiedSince ) { if ( conditionalHeaders . ifUnmodifiedSince < resource . lastModified ) { throw StorageErrorFactory . getConditionNotMet ( context . contextId ! ) ; } return ; } } } private validateCombinations ( context , conditionalHeaders ) { let ifMatch = 0 ; if ( conditionalHeaders . ifMatch && conditionalHeaders . ifMatch . length > 0 ) { if ( conditionalHeaders . ifMatch . length > 1 ) { throw StorageErrorFactory . getMultipleConditionHeadersNotSupported ( context . contextId ! ) ; } ifMatch = 1 ; } let ifModifiedSince = 0 ; if ( conditionalHeaders . ifModifiedSince ) { ifModifiedSince = 1 ; } let ifNoneMatch = 0 ; if ( conditionalHeaders . ifNoneMatch && conditionalHeaders . ifNoneMatch . length > 0 ) { if ( conditionalHeaders . ifNoneMatch . length > 1 ) { throw StorageErrorFactory . getMultipleConditionHeadersNotSupported ( context . contextId ! ) ; } ifNoneMatch = 1 ; } let ifUnmodifiedSince = 0 ; if ( conditionalHeaders . ifUnmodifiedSince ) { ifUnmodifiedSince = 1 ; } if ( ifMatch + ifModifiedSince + ifNoneMatch + ifUnmodifiedSince > 2 ) { throw StorageErrorFactory . getMultipleConditionHeadersNotSupported ( context . contextId ! ) ; } if ( ifMatch + ifModifiedSince + ifNoneMatch + ifUnmodifiedSince === 2 ) { if ( ifNoneMatch + ifModifiedSince === 1 ) { throw StorageErrorFactory . getMultipleConditionHeadersNotSupported ( context . contextId ! ) ; } } } }