Skip to content

Commit

Permalink
[service] OAuth refresh token flow in work
Browse files Browse the repository at this point in the history
  • Loading branch information
newmanw committed Nov 1, 2024
1 parent c38a342 commit 041f96c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 50 deletions.
45 changes: 23 additions & 22 deletions plugins/arcgis/service/src/ArcGISIdentityManagerFactory.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ArcGISIdentityManager, request } from "@esri/arcgis-rest-request"
import { ArcGISAuthConfig, AuthType, FeatureServiceConfig, OAuthAuthConfig, TokenAuthConfig, UsernamePasswordAuthConfig } from './ArcGISConfig'
import { ObservationProcessor } from "./ObservationProcessor";

interface ArcGISIdentityManagerFactory {
create(portal: string, server: string, config: ArcGISAuthConfig, processor?: ObservationProcessor): Promise<ArcGISIdentityManager>
create(portal: string, server: string, config: ArcGISAuthConfig): Promise<ArcGISIdentityManager>
}

const OAuthIdentityManagerFactory: ArcGISIdentityManagerFactory = {
async create(portal: string, server: string, auth: OAuthAuthConfig, processor: ObservationProcessor): Promise<ArcGISIdentityManager> {
async create(portal: string, server: string, auth: OAuthAuthConfig): Promise<ArcGISIdentityManager> {
console.debug('Client ID provided for authentication')
const { clientId, authToken, authTokenExpires, refreshToken, refreshTokenExpires } = auth

Expand All @@ -27,24 +26,27 @@ const OAuthIdentityManagerFactory: ArcGISIdentityManagerFactory = {
httpMethod: 'GET'
});

// TODO Factory should not handle config changes
// Update authToken to new token
const config = await processor.safeGetConfig();
let service = config.featureServices.find(service => service.url === portal)?.auth as OAuthAuthConfig;
const date = new Date();
date.setSeconds(date.getSeconds() + response.expires_in || 0);
service = {
...service,
authToken: response.access_token,
authTokenExpires: date.getTime()
}
// const config = await processor.safeGetConfig();
// let service = config.featureServices.find(service => service.url === portal)?.auth as OAuthAuthConfig;
// const date = new Date();
// date.setSeconds(date.getSeconds() + response.expires_in || 0);
// service = {
// ...service,
// authToken: response.access_token,
// authTokenExpires: date.getTime()
// }
// await processor.putConfig(config)

await processor.putConfig(config)
return ArcGISIdentityManager.fromToken({
clientId: clientId,
token: response.access_token,
tokenExpires: date,
portal: portal
});
// return ArcGISIdentityManager.fromToken({
// clientId: clientId,
// token: response.access_token,
// tokenExpires: date,
// portal: portal
// });

throw new Error('TODO Unsupported')
} catch (error) {
throw new Error('Error occurred when using refresh token')
}
Expand Down Expand Up @@ -86,8 +88,7 @@ const authConfigMap: { [key: string]: ArcGISIdentityManagerFactory } = {
}

export function getIdentityManager(
config: FeatureServiceConfig,
processor: ObservationProcessor
config: FeatureServiceConfig
): Promise<ArcGISIdentityManager> {
const auth = config.auth
const authType = config.auth?.type
Expand All @@ -98,7 +99,7 @@ export function getIdentityManager(
if (!factory) {
throw new Error(`No factory found for type ${authType}`)
}
return factory.create(getPortalUrl(config.url), getServerUrl(config.url), auth, processor)
return factory.create(getPortalUrl(config.url), getServerUrl(config.url), auth)
}


Expand Down
24 changes: 3 additions & 21 deletions plugins/arcgis/service/src/FeatureServiceAdmin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { MageEvent, MageEventRepository } from '@ngageoint/mage.service/lib/enti
import { Layer, Field } from "./AddLayersRequest"
import { Form, FormField, FormFieldType, FormId } from '@ngageoint/mage.service/lib/entities/events/entities.events.forms'
import { ObservationsTransformer } from "./ObservationsTransformer"
import { HttpClient } from './HttpClient'
import { LayerInfoResult, LayerField } from "./LayerInfoResult"
import FormData from 'form-data'
import { request } from '@esri/arcgis-rest-request'
Expand Down Expand Up @@ -433,8 +432,7 @@ export class FeatureServiceAdmin {
*/
private async create(service: FeatureServiceConfig, layer: Layer) {

const httpClient = this.httpClient(service)
const identityManager = await getIdentityManager(service, httpClient)
const identityManager = await getIdentityManager(service)
const url = this.adminUrl(service) + 'addToDefinition'

this._console.info('ArcGIS feature service addToDefinition (create layer) url ' + url)
Expand All @@ -461,8 +459,7 @@ export class FeatureServiceAdmin {

const layer = { fields: fields} as Layer

const httpClient = this.httpClient(service)
const identityManager = await getIdentityManager(service, httpClient)
const identityManager = await getIdentityManager(service)
const url = this.adminUrl(service) + featureLayer.layer.toString() + '/addToDefinition'

this._console.info('ArcGIS feature layer addToDefinition (add fields) url ' + url)
Expand Down Expand Up @@ -501,8 +498,7 @@ export class FeatureServiceAdmin {
const layer = {} as Layer
layer.fields = deleteFields

const httpClient = this.httpClient(service)
const identityManager = await getIdentityManager(service, httpClient)
const identityManager = await getIdentityManager(service)
const url = this.adminUrl(service) + featureLayer.layer.toString() + '/deleteFromDefinition'

this._console.info('ArcGIS feature layer deleteFromDefinition (delete fields) url ' + url)
Expand Down Expand Up @@ -532,18 +528,4 @@ export class FeatureServiceAdmin {
}
return url
}

/**
* Get a HTTP Client with administration token
* @param service feature service
* @returns http client
*/
private httpClient(service: FeatureServiceConfig): HttpClient {
let token = service.adminToken
if (token == null) {
token = service.auth?.type == 'token' ? service.auth.token : ""
}
return new HttpClient(console, token)
}

}
9 changes: 4 additions & 5 deletions plugins/arcgis/service/src/ObservationProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ import { EventTransform } from './EventTransform';
import { GeometryChangedHandler } from './GeometryChangedHandler';
import { EventDeletionHandler } from './EventDeletionHandler';
import { EventLayerProcessorOrganizer } from './EventLayerProcessorOrganizer';
import { FeatureServiceConfig, FeatureLayerConfig, AuthType, OAuthAuthConfig } from "./ArcGISConfig"
import { FeatureServiceConfig, FeatureLayerConfig, AuthType } from "./ArcGISConfig"
import { PluginStateRepository } from '@ngageoint/mage.service/lib/plugins.api'
import { FeatureServiceAdmin } from './FeatureServiceAdmin';
import { HttpClient } from './HttpClient'
import { getIdentityManager } from "./ArcGISIdentityManagerFactory"
import { request } from '@esri/arcgis-rest-request';

Expand Down Expand Up @@ -218,7 +217,7 @@ export class ObservationProcessor {

for (const serv of services) {
try {
const identityManager = await getIdentityManager(serv, new HttpClient(console))
const identityManager = await getIdentityManager(serv)
const response = await request(serv.url, {
authentication: identityManager
}) as FeatureServiceResult
Expand Down Expand Up @@ -292,7 +291,7 @@ export class ObservationProcessor {

if (layerId != null) {
featureLayer.layer = layerId
const identityManager = await getIdentityManager(featureServiceConfig, new HttpClient(console))
const identityManager = await getIdentityManager(featureServiceConfig)
const featureService = new FeatureService(console, featureServiceConfig, identityManager)
const layerInfo = await featureService.queryLayerInfo(layerId);
const url = `${featureServiceConfig.url}/${layerId}`;
Expand Down Expand Up @@ -320,7 +319,7 @@ export class ObservationProcessor {
await admin.updateLayer(featureServiceConfig, featureLayer, layerInfo, this._eventRepo)
}
const info = new LayerInfo(url, events, layerInfo, featureLayer.token)
const identityManager = await getIdentityManager(featureServiceConfig, new HttpClient(console))
const identityManager = await getIdentityManager(featureServiceConfig)
const layerProcessor = new FeatureLayerProcessor(info, config, identityManager,this._console);
this._layerProcessors.push(layerProcessor);
// clearTimeout(this._nextTimeout); // TODO why is this needed?
Expand Down
4 changes: 2 additions & 2 deletions plugins/arcgis/service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {

try {
// Create the IdentityManager instance to validate credentials
await getIdentityManager(service!, processor)
await getIdentityManager(service)
let existingService = config.featureServices.find(service => service.url === url)
if (existingService) {
existingService = { ...existingService }
Expand All @@ -216,7 +216,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
}

try {
const identityManager = await getIdentityManager(featureService, processor)
const identityManager = await getIdentityManager(featureService)
const response = await request(url, {
authentication: identityManager
})
Expand Down

0 comments on commit 041f96c

Please sign in to comment.