Skip to content

Commit

Permalink
TokenHandler.js Implement validation for existence of required keys. …
Browse files Browse the repository at this point in the history
…TokenHandler.test.js Adjust other_tokens fixtures to be nested according to incoming data; formatting.
  • Loading branch information
Anthony Ramirez committed Jan 21, 2025
1 parent ef5244d commit 8092e9f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 28 deletions.
38 changes: 35 additions & 3 deletions web/services/auth/TokenHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,28 @@ export default class OAuthTokenHandler {
* @property {number} expires_in - Integer time in ms until expiration
* @property {string} scope - Scope of token
*/
#oauth_transfer_token_schema = {
access_token: (input_string) => {
if (typeof input_string !== "string") {
throw new Error("Missing required parameter 'access_token': string");
}
},
refresh_token: (input_string) => {
if (typeof input_string !== "string") {
throw new Error("Missing required parameter 'refresh_token': string");
}
},
expires_in: (input_number) => {
if (typeof input_number !== "number") {
throw new Error("Missing required parameter 'expires_in': number");
}
},
scope: (input_string) => {
if (typeof input_string !== "string") {
throw new Error("Missing required parameter 'scope': string");
}
},
};
/**
* @param {object} client_token - OAuth token object from which to extract relevant information
* @param {OAuthTransferToken} client_token.data - Raw data object for OAuth token
Expand Down Expand Up @@ -53,14 +75,24 @@ export default class OAuthTokenHandler {
throw new Error("Unsupported token");
}
case AccessTokenType.GLOBUS_TRANSFER: {
// TODO: confirm existence of required token properties
const transfer_token = this.#client_token.data;
Object.keys(this.#oauth_transfer_token_schema).map((key) => {
// Inspired by: https://stackoverflow.com/a/38616988
this.#oauth_transfer_token_schema[key](transfer_token[key]);
});
break;
}
case AccessTokenType.GLOBUS_DEFAULT: {
// TODO: confirm existence of required token properties
if (!this.#other_tokens_exist) {
throw new Error("Default token handling requires additional transfer tokens in other_tokens field")
throw new Error(
"Default token handling requires additional transfer tokens in other_tokens field",
);
}
const first_token = this.#client_token.data.other_tokens[0];
Object.keys(this.#oauth_transfer_token_schema).map((key) => {
// Inspired by: https://stackoverflow.com/a/38616988
this.#oauth_transfer_token_schema[key](first_token[key]);
});
break;
}
case AccessTokenType.ACCESS_SENTINEL: {
Expand Down
49 changes: 24 additions & 25 deletions web/test/TokenHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,16 @@ describe("OAuthTokenHandler provided with Globus auth resource server", () => {
let second_other_token;
beforeEach(() => {
first_other_token = {
data: {
resource_server: "transfer.api.globus.org",
other_tokens: [],
access_token: "first_other.access_token",
refresh_token: "first_other.refresh_token",
expires_in: 123456789,
scope: "test::urn::transfer.globus.org::all",
},
resource_server: "transfer.api.globus.org",
other_tokens: [],
access_token: "first_other.access_token",
refresh_token: "first_other.refresh_token",
expires_in: 123456789,
scope: "test::urn::transfer.globus.org::all",
};
second_other_token = {
data: {
access_token: "second_other.access_token",
refresh_token: "second_other.access_token",
},
access_token: "second_other.access_token",
refresh_token: "second_other.access_token",
};
test_token = {
data: {
Expand Down Expand Up @@ -70,7 +66,7 @@ describe("OAuthTokenHandler provided with Globus auth resource server", () => {
});
it("should return an object with only the token type from constructOptionalData when other_tokens field has valid contents", () => {
const token_handler = new OAuthTokenHandler(test_token);
const token_context = { scope: first_other_token.data.scope };
const token_context = { scope: first_other_token.scope };
expect(token_handler.constructOptionalData(token_context)).to.deep.equal({
type: AccessTokenType.GLOBUS_DEFAULT,
});
Expand All @@ -81,15 +77,14 @@ describe("OAuthTokenHandler provided with Globus transfer resource server", () =
let test_token;
let first_other_token;
beforeEach(() => {
first_other_token = { // This token should be ignored
data: {
resource_server: "transfer.api.globus.org",
other_tokens: [],
access_token: "first_other.access_token",
refresh_token: "first_other.refresh_token",
expires_in: 123456789,
scope: "test::urn::transfer.globus.org::all",
},
first_other_token = {
// This token should be ignored
resource_server: "transfer.api.globus.org",
other_tokens: [],
access_token: "first_other.access_token",
refresh_token: "first_other.refresh_token",
expires_in: 123456789,
scope: "test::urn::transfer.globus.org::all",
};
test_token = {
data: {
Expand All @@ -113,12 +108,16 @@ describe("OAuthTokenHandler provided with Globus transfer resource server", () =
it("should throw an error during constructOptionalData when a collection_id is not provided in context", () => {
const token_handler = new OAuthTokenHandler(test_token);
const token_context = { scope: test_token.data.scope };
expect(() => {const optional_data = token_handler.constructOptionalData(token_context)}).to.throw("Transfer token received without collection context");
expect(() => {
const optional_data = token_handler.constructOptionalData(token_context);
}).to.throw("Transfer token received without collection context");
});
it("should throw an error during constructOptionalData when a scope is not provided in context", () => {
const token_handler = new OAuthTokenHandler(test_token);
const token_context = { collection_id: "mock id" };
expect(() => {const optional_data = token_handler.constructOptionalData(token_context)}).to.throw("Transfer token received without scope context");
expect(() => {
const optional_data = token_handler.constructOptionalData(token_context);
}).to.throw("Transfer token received without scope context");
});
it("should return appropriate optional data from constructOptionalData when necessary context is provided", () => {
const test_collection_id = "test_collection_id";
Expand All @@ -131,4 +130,4 @@ describe("OAuthTokenHandler provided with Globus transfer resource server", () =
expect(optional_data.other).to.equal(expected_other_field);
expect(optional_data.type).to.equal(AccessTokenType.GLOBUS_TRANSFER);
});
});
});

0 comments on commit 8092e9f

Please sign in to comment.