Skip to content

Commit

Permalink
Merge pull request #417 from Esri/f/ensure-mixed-casing-works-with-fe…
Browse files Browse the repository at this point in the history
…deration

fix(arcgis-rest-auth): Allow mixed casing of federated server urls
  • Loading branch information
john gravois authored Dec 3, 2018
2 parents 25b70ad + 5344105 commit c4e0697
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 3 deletions.
7 changes: 4 additions & 3 deletions packages/arcgis-rest-auth/src/UserSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ export class UserSession implements IAuthenticationManager {
/^https?:\/\/\S+\.arcgis\.com.+/.test(url)
) {
return this.getFreshToken(requestOptions);
} else if (new RegExp(this.portal).test(url)) {
} else if (new RegExp(this.portal, "i").test(url)) {
return this.getFreshToken(requestOptions);
} else {
return this.getTokenForServer(url, requestOptions);
Expand Down Expand Up @@ -708,7 +708,8 @@ export class UserSession implements IAuthenticationManager {
requestOptions?: ITokenRequestOptions
) {
// requests to /rest/services/ and /rest/admin/services/ are both valid
const [root] = url.split(/\/rest(\/admin)?\/services\//);
// Federated servers may have inconsistent casing, so lowerCase it
const [root] = url.toLowerCase().split(/\/rest(\/admin)?\/services\//);
const existingToken = this.trustedServers[root];

if (existingToken && existingToken.expires.getTime() > Date.now()) {
Expand All @@ -732,7 +733,7 @@ export class UserSession implements IAuthenticationManager {
*/
if (
!owningSystemUrl ||
!new RegExp(owningSystemUrl).test(this.portal)
!new RegExp(owningSystemUrl, "i").test(this.portal)
) {
throw new ArcGISAuthError(
`${url} is not federated with ${this.portal}.`,
Expand Down
84 changes: 84 additions & 0 deletions packages/arcgis-rest-auth/test/UserSession.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,90 @@ describe("UserSession", () => {
});
});

it("should return unexpired tokens for the configured portal domain, regardless of CASING", done => {
// This was a real configuration discovered on a portal instance
const session = new UserSession({
clientId: "id",
token: "token",
tokenExpires: TOMORROW,
portal: "https://pnp00035.esri.com/sharing/rest"
});

session
.getToken("https://PNP00035.esri.com/sharing/rest/portals/self")
.then(token => {
expect(token).toBe("token");
done();
})
.catch(e => {
fail(e);
});
});

it("should fetch token when contacting a server that is federated, even if on same domain, regardless of domain casing", done => {
// This was a real configuration discovered on a portal instance
// apparently when federating servers, the UI does not force the
// server url to lowercase, and this any feature service items generated
// will have the server name using the casing the admin entered.
// this is just a test to ensure that the mis-matched casing does not
// break the federation flow.
const session = new UserSession({
clientId: "id",
token: "existing-session-token",
refreshToken: "refresh",
tokenExpires: TOMORROW,
portal: "https://pnp00035.esri.com/portal/sharing/rest"
});

fetchMock.postOnce("https://pnp00035.esri.com/server/rest/info", {
currentVersion: 10.61,
fullVersion: "10.6.1",
owningSystemUrl: "https://pnp00035.esri.com/portal",
authInfo: {
isTokenBasedSecurity: true,
tokenServicesUrl:
"https://pnp00035.esri.com/portal/sharing/rest/generateToken"
}
});

fetchMock.postOnce("https://pnp00035.esri.com/portal/sharing/rest/info", {
owningSystemUrl: "https://pnp00035.esri.com/portal",
authInfo: {
tokenServicesUrl:
"https://pnp00035.esri.com/portal/sharing/rest/generateToken",
isTokenBasedSecurity: true
}
});

fetchMock.postOnce(
"https://pnp00035.esri.com/portal/sharing/rest/generateToken",
{
token: "new-server-token",
expires: TOMORROW
}
);

// request the token twice, for the same domain, but with different casing
// and we expect a single POST to generate a token once
session
.getToken(
"https://PNP00035.esri.com/server/rest/services/Hosted/perimeters_dd83/FeatureServer"
)
.then(token => {
expect(token).toBe("new-server-token");
return session.getToken(
"https://pnp00035.esri.com/server/rest/services/Hosted/otherService/FeatureServer"
);
})
.then(token => {
expect(token).toBe("new-server-token");
done();
})
.catch(e => {
fail(e);
});
});

it("should fetch new tokens when tokens for trusted arcgis.com domains are expired", done => {
const session = new UserSession({
clientId: "id",
Expand Down

0 comments on commit c4e0697

Please sign in to comment.