UNPKG

azurite

Version:

An open source Azure Storage API compatible server

95 lines 5.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const models_1 = require("../generated/artifacts/models"); const operation_1 = tslib_1.__importDefault(require("../generated/artifacts/operation")); const CONTAINER_PUBLIC_READ_OPERATIONS = new Set([ operation_1.default.Container_GetProperties, operation_1.default.Container_GetPropertiesWithHead, operation_1.default.Container_GetAccessPolicy, operation_1.default.Container_ListBlobFlatSegment, operation_1.default.Container_ListBlobHierarchySegment, operation_1.default.Blob_Download, operation_1.default.Blob_GetProperties, operation_1.default.PageBlob_GetPageRanges, // TODO: Not sure operation_1.default.PageBlob_GetPageRangesDiff, // TODO: Not sure operation_1.default.BlockBlob_GetBlockList // TODO: Not sure ]); const BLOB_PUBLIC_READ_OPERATIONS = new Set([ operation_1.default.Blob_Download, operation_1.default.Blob_GetProperties, operation_1.default.PageBlob_GetPageRanges, // TODO: Not sure operation_1.default.PageBlob_GetPageRangesDiff, // TODO: Not sure operation_1.default.BlockBlob_GetBlockList // TODO: Not sure ]); class PublicAccessAuthenticator { constructor(blobMetadataStore, logger) { this.blobMetadataStore = blobMetadataStore; this.logger = logger; } async validate(req, context) { this.logger.info(`PublicAccessAuthenticator:validate() Start validation against public access.`, context.contextId); this.logger.debug("PublicAccessAuthenticator:validate() Getting account properties...", context.contextId); const account = context.context.account; const containerName = context.context.container; const blobName = context.context.blob; this.logger.debug( // tslint:disable-next-line:max-line-length `PublicAccessAuthenticator:validate() Retrieved account name from context: ${account}, container: ${containerName}, blob: ${blobName}`, context.contextId); if (containerName === undefined) { this.logger.info( // tslint:disable-next-line:max-line-length `PublicAccessAuthenticator:validate() Skip public access authentication. Container name is undefined.`, context.contextId); return undefined; } const containerPublicAccessType = await this.getContainerPublicAccessType(account, containerName, context); if (containerPublicAccessType === undefined) { this.logger.debug( // tslint:disable-next-line:max-line-length `PublicAccessAuthenticator:validate() Skip public access authentication. Cannot get public access type for container ${containerName}`, context.contextId); return undefined; } this.logger.debug(`PublicAccessAuthenticator:validate() Public access type for container ${containerName} is ${JSON.stringify(containerPublicAccessType)}`, context.contextId); const operation = context.operation; if (operation === undefined) { throw new Error( // tslint:disable-next-line:max-line-length `PublicAccessAuthenticator:validate() Operation shouldn't be undefined. Please make sure DispatchMiddleware is hooked before authentication related middleware.`); } if (containerPublicAccessType === models_1.PublicAccessType.Container) { if (CONTAINER_PUBLIC_READ_OPERATIONS.has(operation)) { this.logger.debug(`PublicAccessAuthenticator:validate() Operation ${operation_1.default[operation]} is in container level public access list. Validation passed.`, context.contextId); return true; } } else if (containerPublicAccessType === models_1.PublicAccessType.Blob) { if (BLOB_PUBLIC_READ_OPERATIONS.has(operation)) { this.logger.debug(`PublicAccessAuthenticator:validate() Operation ${operation_1.default[operation]} is in blob level public access list. Validation passed.`, context.contextId); return true; } } else { throw Error(`PublicAccessAuthenticator:validate() Unsupported containerPublicAccessType ${containerPublicAccessType}`); } this.logger.debug(`PublicAccessAuthenticator:validate() Operation ${operation_1.default[operation]} is not in container neither blob level public access list. Validation failed.`, context.contextId); // TODO: Make validate() return values into 3 candidates (true, false, and error thrown) // True means validation passed // False means validation doesn't match (due to not match this validation pattern), then goto next authenticator // Error means validation failed, response will return error immediately return undefined; } async getContainerPublicAccessType(account, container, context) { try { const containerModel = await this.blobMetadataStore.getContainerACL(context, account, container); if (containerModel === undefined) { return undefined; } return containerModel.properties.publicAccess; } catch (err) { return undefined; } } } exports.default = PublicAccessAuthenticator; //# sourceMappingURL=PublicAccessAuthenticator.js.map