Skip to content

Commit

Permalink
updates from pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanslatten committed Oct 31, 2024
1 parent 8babd64 commit 1db79ba
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 29 deletions.
15 changes: 8 additions & 7 deletions plugins/arcgis/service/src/ArcGISIdentityManagerFactory.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { ArcGISIdentityManager } from "@esri/arcgis-rest-request"
import { ArcGISIdentityManager, request } from "@esri/arcgis-rest-request"
import { ArcGISAuthConfig, AuthType, FeatureServiceConfig, OAuthAuthConfig, TokenAuthConfig, UsernamePasswordAuthConfig } from './ArcGISConfig'
import { HttpClient } from "./HttpClient";
import { ObservationProcessor } from "./ObservationProcessor";

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

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

Expand All @@ -24,7 +23,10 @@ const OAuthIdentityManagerFactory: ArcGISIdentityManagerFactory = {
// TODO: find a way without using constructor nor httpClient
const url = `${portal}/oauth2/token?client_id=${clientId}&refresh_token=${refreshToken}&grant_type=refresh_token`
try {
const response = await httpClient.sendGet(url)
const response = await request(url, {
httpMethod: 'GET'
});

// Update authToken to new token
const config = await processor.safeGetConfig();
let service = config.featureServices.find(service => service.url === portal)?.auth as OAuthAuthConfig;
Expand Down Expand Up @@ -85,7 +87,6 @@ const authConfigMap: { [key: string]: ArcGISIdentityManagerFactory } = {

export function getIdentityManager(
config: FeatureServiceConfig,
httpClient: HttpClient, // TODO remove in favor of an open source lib like axios
processor: ObservationProcessor
): Promise<ArcGISIdentityManager> {
const auth = config.auth
Expand All @@ -97,7 +98,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, httpClient, processor)
return factory.create(getPortalUrl(config.url), getServerUrl(config.url), auth, processor)
}


Expand Down
32 changes: 29 additions & 3 deletions plugins/arcgis/service/src/ObservationProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { EventTransform } from './EventTransform';
import { GeometryChangedHandler } from './GeometryChangedHandler';
import { EventDeletionHandler } from './EventDeletionHandler';
import { EventLayerProcessorOrganizer } from './EventLayerProcessorOrganizer';
import { FeatureServiceConfig, FeatureLayerConfig, AuthType } from "./ArcGISConfig"
import { FeatureServiceConfig, FeatureLayerConfig, AuthType, OAuthAuthConfig } from "./ArcGISConfig"
import { PluginStateRepository } from '@ngageoint/mage.service/lib/plugins.api'
import { FeatureServiceAdmin } from './FeatureServiceAdmin';

Expand Down Expand Up @@ -120,8 +120,13 @@ export class ObservationProcessor {
* Gets the current configuration from the database.
* @returns The current configuration from the database.
*/
public async safeGetConfig(): Promise<ArcGISPluginConfig> {
return await this._stateRepo.get().then(x => !!x ? x : this._stateRepo.put(defaultArcGISPluginConfig))
public async safeGetConfig(showFeatureAuth?: boolean): Promise<ArcGISPluginConfig> {
const state = await this._stateRepo.get();
if (!state) return await this._stateRepo.put(defaultArcGISPluginConfig);
if (!showFeatureAuth) {
state.featureServices = state.featureServices.map((service) => this.sanitizeFeatureService(service, AuthType.OAuth));
}
return state;
}

/**
Expand All @@ -132,6 +137,14 @@ export class ObservationProcessor {
return await this._stateRepo.put(newConfig);
}

/**
* Updates the confguration in the state repo.
* @param newConfig The new config to put into the state repo.
*/
public async patchConfig(newConfig: ArcGISPluginConfig): Promise<ArcGISPluginConfig> {
return await this._stateRepo.patch(newConfig);
}

/**
* Gets the current configuration and updates the processor if needed
* @returns The current configuration from the database.
Expand All @@ -151,6 +164,19 @@ export class ObservationProcessor {
return config
}

private sanitizeFeatureService(config: FeatureServiceConfig, type: AuthType): FeatureServiceConfig {
if (type === AuthType.OAuth) {
const newAuth = Object.assign({}, config.auth) as OAuthAuthConfig;
delete newAuth.refreshToken;
delete newAuth.refreshTokenExpires;
return {
...config,
auth: newAuth
}
}
return config;
}

/**
* Starts the processor.
*/
Expand Down
15 changes: 6 additions & 9 deletions plugins/arcgis/service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { SettingPermission } from '@ngageoint/mage.service/lib/entities/authoriz
import { ArcGISPluginConfig } from './ArcGISPluginConfig'
import { AuthType } from './ArcGISConfig'
import { ObservationProcessor } from './ObservationProcessor'
import { HttpClient } from './HttpClient'
import { ArcGISIdentityManager, request } from "@esri/arcgis-rest-request"
import { FeatureServiceConfig } from './ArcGISConfig'
import { URL } from "node:url"
Expand Down Expand Up @@ -157,7 +156,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
console.info('Applying ArcGIS plugin config...')
const arcConfig = req.body as ArcGISPluginConfig
const configString = JSON.stringify(arcConfig)
processor.putConfig(arcConfig)
processor.patchConfig(arcConfig)
res.sendStatus(200)
})

Expand All @@ -179,17 +178,16 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
}

try {
const httpClient = new HttpClient(console)
// Create the IdentityManager instance to validate credentials
await getIdentityManager(service!, httpClient, processor)
await getIdentityManager(service!, processor)
let existingService = config.featureServices.find(service => service.url === url)
if (existingService) {
existingService = { ...existingService }
} else {
config.featureServices.push(service)
}

await processor.putConfig(config)
console.log('values patch')
await processor.patchConfig(config)
return res.send(service)
} catch (err) {
return res.send('Invalid credentials provided to communicate with feature service').status(400)
Expand All @@ -203,10 +201,9 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
if (!featureService) {
return res.status(400)
}

const httpClient = new HttpClient(console)

try {
const identityManager = await getIdentityManager(featureService, httpClient, processor)
const identityManager = await getIdentityManager(featureService, processor)
const response = await request(url, {
authentication: identityManager
})
Expand Down
10 changes: 0 additions & 10 deletions plugins/arcgis/web-app/projects/main/src/lib/ArcGISConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,6 @@ export interface OAuthAuthConfig {
* The expiration date for the temporary token
*/
authTokenExpires?: string

/**
* The Refresh token for OAuth
*/
refreshToken?: string

/**
* The expiration date for the Refresh token
*/
refreshTokenExpires?: string
}

/**
Expand Down

0 comments on commit 1db79ba

Please sign in to comment.