Skip to content

Commit

Permalink
Merge pull request #2141 from AzureAD/msal-common-cacheType-validation
Browse files Browse the repository at this point in the history
[msal-common] Add validation to cache entities
  • Loading branch information
sameerag committed Aug 21, 2020
2 parents 48cd24b + 5c802e9 commit ac98ca7
Show file tree
Hide file tree
Showing 21 changed files with 300 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "patch",
"comment": "update APP_META_DATA to APP_METADATA",
"packageName": "@azure/msal-browser",
"email": "sameera.gajjarapu@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-08-21T21:13:27.893Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "patch",
"comment": "Adds checks for cache entities",
"packageName": "@azure/msal-common",
"email": "sameera.gajjarapu@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-08-21T21:14:13.967Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "update APP_META_DATA to APP_METADATA",
"packageName": "@azure/msal-node",
"email": "sameera.gajjarapu@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-08-21T21:14:30.830Z"
}
4 changes: 2 additions & 2 deletions lib/msal-browser/src/cache/BrowserStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class BrowserStorage extends CacheManager {
switch (type) {
case CacheSchemaType.ACCOUNT:
case CacheSchemaType.CREDENTIAL:
case CacheSchemaType.APP_META_DATA:
case CacheSchemaType.APP_METADATA:
this.windowStorage.setItem(key, JSON.stringify(value));
break;
case CacheSchemaType.TEMPORARY: {
Expand Down Expand Up @@ -166,7 +166,7 @@ export class BrowserStorage extends CacheManager {
}
}
}
case CacheSchemaType.APP_META_DATA: {
case CacheSchemaType.APP_METADATA: {
return (JSON.parse(value) as AppMetadataEntity);
}
case CacheSchemaType.TEMPORARY: {
Expand Down
8 changes: 4 additions & 4 deletions lib/msal-common/src/cache/CacheManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { AccountCache, AccountFilter, CredentialFilter, CredentialCache } from "./utils/CacheTypes";
import { CacheRecord } from "./entities/CacheRecord";
import { CacheSchemaType, CredentialType, Constants, APP_META_DATA } from "../utils/Constants";
import { CacheSchemaType, CredentialType, Constants, APP_METADATA } from "../utils/Constants";
import { CredentialEntity } from "./entities/CredentialEntity";
import { ScopeSet } from "../request/ScopeSet";
import { AccountEntity } from "./entities/AccountEntity";
Expand Down Expand Up @@ -335,7 +335,7 @@ export abstract class CacheManager implements ICacheManager {
const allCacheKeys = this.getKeys();
allCacheKeys.forEach((cacheKey) => {
if (this.isAppMetadata(cacheKey)) {
this.removeItem(cacheKey, CacheSchemaType.APP_META_DATA);
this.removeItem(cacheKey, CacheSchemaType.APP_METADATA);
}
});

Expand Down Expand Up @@ -478,7 +478,7 @@ export abstract class CacheManager implements ICacheManager {

/**
* Returns a valid AccountEntity if key and object contain correct values, null otherwise.
* @param key
* @param key
*/
private getAccountEntity(key: string): AccountEntity | null {
// don't parse any non-account type cache entities
Expand Down Expand Up @@ -507,7 +507,7 @@ export abstract class CacheManager implements ICacheManager {
* @param key
*/
private isAppMetadata(key: string): boolean {
return key.indexOf(APP_META_DATA) !== -1;
return key.indexOf(APP_METADATA) !== -1;
}

/**
Expand Down
24 changes: 21 additions & 3 deletions lib/msal-common/src/cache/entities/AccessTokenEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { TimeUtils } from "../../utils/TimeUtils";

/**
* ACCESS_TOKEN Credential Type
*
*
* Key:Value Schema:
*
*
* Key Example: uid.utid-login.microsoftonline.com-accesstoken-clientId-contoso.com-user.read
*
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
Expand Down Expand Up @@ -83,4 +83,22 @@ export class AccessTokenEntity extends CredentialEntity {

return atEntity;
}

/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isAccessTokenEntity(entity: object): boolean {

return (
entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("credentialType") &&
entity.hasOwnProperty("realm") &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("secret") &&
entity.hasOwnProperty("target") &&
entity["credentialType"] === CredentialType.ACCESS_TOKEN
);
}
}
28 changes: 22 additions & 6 deletions lib/msal-common/src/cache/entities/AccountEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import { ClientAuthError } from "../../error/ClientAuthError";

/**
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
*
*
* Key : Value Schema
*
*
* Key: <home_account_id>-<environment>-<realm*>
*
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
Expand All @@ -35,7 +35,7 @@ import { ClientAuthError } from "../../error/ClientAuthError";
* name: Full name for the account, including given name and family name,
* clientInfo: Full base64 encoded client info received from ESTS
* lastModificationTime: last time this entity was modified in the cache
* lastModificationApp:
* lastModificationApp:
* }
*/
export class AccountEntity {
Expand Down Expand Up @@ -140,7 +140,7 @@ export class AccountEntity {
if (StringUtils.isEmpty(env)) {
throw ClientAuthError.createInvalidCacheEnvironmentError();
}

account.environment = env;
account.realm = idToken.claims.tid;

Expand Down Expand Up @@ -170,7 +170,7 @@ export class AccountEntity {

account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
account.homeAccountId = idToken.claims.sub;

const reqEnvironment = authority.canonicalAuthorityUrlComponents.HostNameAndPort;
const env = TrustedAuthority.getCloudDiscoveryMetadata(reqEnvironment) ? TrustedAuthority.getCloudDiscoveryMetadata(reqEnvironment).preferred_cache : "";

Expand All @@ -185,4 +185,20 @@ export class AccountEntity {

return account;
}

/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isAccountEntity(entity: object): boolean {

return (
entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("realm") &&
entity.hasOwnProperty("localAccountId") &&
entity.hasOwnProperty("username") &&
entity.hasOwnProperty("authorityType")
);
}
}
26 changes: 19 additions & 7 deletions lib/msal-common/src/cache/entities/AppMetadataEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { APP_META_DATA, Separators } from "../../utils/Constants";
import { APP_METADATA, Separators } from "../../utils/Constants";

/**
* APP_META_DATA Cache
*
* APP_METADATA Cache
*
* Key:Value Schema:
*
*
* Key: appmetadata-<environment>-<client_id>
*
* Value:
*
* Value:
* {
* clientId: client ID of the application
* environment: entity that issued the token, represented as a full host
Expand All @@ -27,7 +27,19 @@ export class AppMetadataEntity {
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
*/
generateAppMetaDataEntityKey(): string {
const appMetaDataKeyArray: Array<string> = [APP_META_DATA, this.environment, this.clientId];
const appMetaDataKeyArray: Array<string> = [APP_METADATA, this.environment, this.clientId];
return appMetaDataKeyArray.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}

/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isAppMetadataEntity(key: string, entity: object): boolean {
return (
(key.indexOf(APP_METADATA) === 0) &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("environment")
);
}
}
6 changes: 3 additions & 3 deletions lib/msal-common/src/cache/entities/CredentialEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { ClientAuthError } from "../../error/ClientAuthError";

/**
* Base type for credentials to be stored in the cache: eg: ACCESS_TOKEN, ID_TOKEN etc
*
*
* Key:Value Schema:
*
*
* Key: <home_account_id*>-<environment>-<credential_type>-<client_id>-<realm*>-<target*>
*
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
Expand Down
23 changes: 20 additions & 3 deletions lib/msal-common/src/cache/entities/IdTokenEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { CredentialType } from "../../utils/Constants";

/**
* ID_TOKEN Cache
*
*
* Key:Value Schema:
*
*
* Key Example: uid.utid-login.microsoftonline.com-idtoken-clientId-contoso.com-
*
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
Expand Down Expand Up @@ -51,4 +51,21 @@ export class IdTokenEntity extends CredentialEntity {

return idTokenEntity;
}

/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isIdTokenEntity(entity: object): boolean {

return (
entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("credentialType") &&
entity.hasOwnProperty("realm") &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("secret") &&
entity["credentialType"] === CredentialType.ID_TOKEN
);
}
}
22 changes: 19 additions & 3 deletions lib/msal-common/src/cache/entities/RefreshTokenEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { CredentialType } from "../../utils/Constants";

/**
* REFRESH_TOKEN Cache
*
*
* Key:Value Schema:
*
*
* Key Example: uid.utid-login.microsoftonline.com-refreshtoken-clientId--
*
*
* Value:
* {
* homeAccountId: home account identifier for the auth scheme,
Expand Down Expand Up @@ -55,4 +55,20 @@ export class RefreshTokenEntity extends CredentialEntity {

return rtEntity;
}

/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isRefreshTokenEntity(entity: object): boolean {

return (
entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("credentialType") &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("secret") &&
entity["credentialType"] === CredentialType.REFRESH_TOKEN
);
}
}
33 changes: 33 additions & 0 deletions lib/msal-common/src/cache/entities/ServerTelemetryEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { SERVER_TELEM_CONSTANTS } from "../../utils/Constants";

export class ServerTelemetryEntity {
failedRequests: Array<string|number>;
errors: string[];
errorCount: number;
cacheHits: number;

/**
* validates if a given cache entry is "Telemetry", parses <key,value>
* @param key
* @param entity
*/
static isServerTelemetryEntity(key: string, entity?: object): boolean {

const validateKey: boolean = key.indexOf(SERVER_TELEM_CONSTANTS.CACHE_KEY) === 0;
let validateEntity: boolean = true;

if (entity) {
validateEntity =
entity.hasOwnProperty("failedRequests") &&
entity.hasOwnProperty("errors") &&
entity.hasOwnProperty("errorCount") &&
entity.hasOwnProperty("cacheHits");
}

return validateKey && validateEntity;
}
}
6 changes: 3 additions & 3 deletions lib/msal-common/src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export enum CredentialType {
export enum CacheSchemaType {
ACCOUNT = "Account",
CREDENTIAL = "Credential",
APP_META_DATA = "AppMetadata",
APP_METADATA = "AppMetadata",
TEMPORARY = "TempCache",
TELEMETRY = "Telemetry",
}
Expand All @@ -245,13 +245,13 @@ export enum CacheType {
ACCESS_TOKEN = 2001,
REFRESH_TOKEN = 2002,
ID_TOKEN = 2003,
APP_META_DATA = 3001
APP_METADATA = 3001
};

/**
* More Cache related constants
*/
export const APP_META_DATA = "appmetadata";
export const APP_METADATA = "appmetadata";
export const ClientInfo = "client_info";

export const SERVER_TELEM_CONSTANTS = {
Expand Down
6 changes: 3 additions & 3 deletions lib/msal-common/test/cache/CacheManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class TestStorageManager extends CacheManager {
}
break;
}
case CacheSchemaType.APP_META_DATA: {
case CacheSchemaType.APP_METADATA: {
if (!!store[key]) {
delete store[key];
result = true;
Expand Down Expand Up @@ -258,7 +258,7 @@ describe("CacheManager.ts test cases", () => {
let accounts = cacheManager.getAccountsFilteredBy(successFilter);
expect(Object.keys(accounts).length).to.eql(1);
sinon.restore();

const wrongFilter: AccountFilter = { environment: "Wrong Env" };
accounts = cacheManager.getAccountsFilteredBy(wrongFilter);
expect(Object.keys(accounts).length).to.eql(0);
Expand Down Expand Up @@ -373,7 +373,7 @@ describe("CacheManager.ts test cases", () => {

it("removeAppMetadata", () => {
cacheManager.removeAppMetadata();

expect(store["appmetadata-login.microsoftonline.com-mock_client_id"]).to.be.undefined;
});

Expand Down
Loading

0 comments on commit ac98ca7

Please sign in to comment.