azurite
Version:
An open source Azure Storage API compatible server
95 lines • 5.41 kB
JavaScript
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
;