import { Context, Object } from "./context"; import { GenericResource } from "azure-arm-resource/lib/resource/models"; import { Application } from "azure-graph/lib/models"; import { Options } from "./options"; import { Client, Tenant } from "./client"; export abstract class Rule { protected context: Context; options: Options; name: string; protected constructor(context: Context, options: Options) { this.context = context; this.options = options; this.name = this.constructor.name; } abstract run(client: Client): Promise; protected report( object: GenericResource | Application | Tenant, messageId: string, data?: any ) { this.context.report({ rule: this.name, severity: this.options.severity, object: toObject(object), messageId, data }); } } function toObject(object: any): Object { let result: Object | null = null; if ("id" in object && "name" in object && "location" in object) { result = { type: "resource", id: object.id, name: object.name }; } else if ("appId" in object && "displayName" in object) { result = { type: "application", id: `/application/${object.appId}`, name: object.displayName }; } else if ("objectId" in object && "displayName" in object) { if (object.objectType === "User" || object.objectType === "Group") { const type = object.objectType.toLowerCase(); result = { type, id: `/${type}/${object.objectId}`, name: object.displayName }; } else if ("domain" in object) { result = { type: "tenant", id: `/tenant/${object.objectId}`, name: object.displayName + (object.domain ? ` (${object.domain})` : "") }; } } if (!result || !result.type || !result.id || !result.name) { throw new Error(`Invalid object: ${JSON.stringify(object)}`); } return result; }