Skip to content

Commit

Permalink
Merge pull request #342 from vscheuber/main
Browse files Browse the repository at this point in the history
Support authentication settings
  • Loading branch information
vscheuber authored Nov 4, 2023
2 parents 3d04071 + e2f932b commit 1a4192a
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- rockcarver/frodo-cli#217: Support for authentication settings through new `frodo.authn.settings` module.

## [2.0.0-47] - 2023-11-02

### Added
Expand Down
6 changes: 5 additions & 1 deletion src/api/AuthenticationSettingsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export type AuthenticationSettingsSkeleton = IdObjectSkeletonInterface & {
* Get authentication settings
* @returns {Promise<AuthenticationSettingsSkeleton>} a promise that resolves to an authentication settings object
*/
export async function getAuthenticationSettings({ state }: { state: State }) {
export async function getAuthenticationSettings({
state,
}: {
state: State;
}): Promise<AuthenticationSettingsSkeleton> {
debugMessage({
message: `AuthenticationSettingsApi.getAuthenticationSettings: start`,
state,
Expand Down
5 changes: 5 additions & 0 deletions src/lib/FrodoLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import AdminOps, { Admin } from '../ops/AdminOps';
import AgentOps, { Agent } from '../ops/AgentOps';
import ApplicationOps, { Application } from '../ops/ApplicationOps';
import AuthenticateOps, { Authenticate } from '../ops/AuthenticateOps';
import AuthenticationSettingsOps, {
AuthenticationSettings,
} from '../ops/AuthenticationSettingsOps';
import CirclesOfTrustOps, { CirclesOfTrust } from '../ops/CirclesOfTrustOps';
import AdminFederationOps, {
AdminFederation,
Expand Down Expand Up @@ -67,6 +70,7 @@ export type Frodo = {
authn: {
journey: Journey;
node: Node;
settings: AuthenticationSettings;
};

authz: {
Expand Down Expand Up @@ -204,6 +208,7 @@ const FrodoLib = (config: StateInterface = {}): Frodo => {
authn: {
journey: JourneyOps(state),
node: NodeOps(state),
settings: AuthenticationSettingsOps(state),
},

authz: {
Expand Down
40 changes: 18 additions & 22 deletions src/ops/AuthenticationSettingsOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { debugMessage } from '../utils/Console';
import { getMetadata } from '../utils/ExportImportUtils';
import { type ExportMetaData } from './OpsTypes';

export type Idp = {
export type AuthenticationSettings = {
/**
* Read authentication settings
* @returns {Promise<AuthenticationSettingsSkeleton>} a promise that resolves an authentication settings object
Expand Down Expand Up @@ -36,7 +36,7 @@ export type Idp = {
): Promise<AuthenticationSettingsSkeleton>;
};

export default (state: State): Idp => {
export default (state: State): AuthenticationSettings => {
return {
async readAuthenticationSettings() {
return readAuthenticationSettings({ state });
Expand Down Expand Up @@ -89,8 +89,8 @@ export async function readAuthenticationSettings({
}: {
state: State;
}): Promise<AuthenticationSettingsSkeleton> {
const { result } = await _getAuthenticationSettings({ state });
return result;
const settings = await _getAuthenticationSettings({ state });
return settings;
}

export async function updateAuthenticationSettings({
Expand Down Expand Up @@ -138,23 +138,6 @@ export async function exportAuthenticationSettings({
return exportData;
}

/**
* Export authentication settings
* @returns {Promise<AuthenticationSettingsExportInterface>} a promise that resolves to a AuthenticationSettingsExportInterface object
*/
export async function exportSocialProviders({
state,
}: {
state: State;
}): Promise<AuthenticationSettingsExportInterface> {
const exportData = createAuthenticationSettingsExportTemplate({ state });
const settingsData = await readAuthenticationSettings({
state,
});
exportData.authentication = settingsData;
return exportData;
}

/**
* Import authentication settings
* @param {AuthenticationSettingsExportInterface} importData import data
Expand All @@ -178,7 +161,20 @@ export async function importAuthenticationSettings({
errors.push(error);
}
if (errors.length) {
const errorMessages = errors.map((error) => error.message).join('\n');
const errorMessages = errors
.map(
(error) =>
`${error.response?.status}${
error.response?.data['reason']
? ' ' + error.response?.data['reason']
: ''
}${
error.response?.data['message']
? ' - ' + error.response?.data['message']
: ''
}`
)
.join('\n');
throw new Error(`Import error:\n${errorMessages}`);
}
return response;
Expand Down
88 changes: 88 additions & 0 deletions src/ops/ManagedObjectOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
queryAllManagedObjectsByType,
queryManagedObjects as _queryManagedObjects,
} from '../api/ManagedObjectApi';
import Constants from '../shared/Constants';
import { State } from '../shared/State';

export type ManagedObject = {
Expand Down Expand Up @@ -107,6 +108,12 @@ export type ManagedObject = {
* @returns {Promise<string>} resolved full name or uuid if any error occurs during reslution
*/
resolveFullName(type: string, id: string): Promise<string>;
/**
* Resolve a perpetrator's uuid to a human readable string identifying the perpetrator
* @param {string} id managed object _id
* @returns {Promise<string>} resolved perpetrator descriptive string or uuid if any error occurs during reslution
*/
resolvePerpetratorUuid(id: string): Promise<string>;
};

export default (state: State): ManagedObject => {
Expand Down Expand Up @@ -171,6 +178,9 @@ export default (state: State): ManagedObject => {
async resolveFullName(type: string, id: string) {
return resolveFullName({ type, id, state });
},
async resolvePerpetratorUuid(id: string): Promise<string> {
return resolvePerpetratorUuid({ id, state });
},
};
};

Expand Down Expand Up @@ -342,3 +352,81 @@ export async function resolveFullName({
}
return id;
}

export async function resolvePerpetratorUuid({
id,
state,
}: {
id: string;
state: State;
}): Promise<string> {
try {
if (state.getDeploymentType() === Constants.CLOUD_DEPLOYMENT_TYPE_KEY) {
const lookupPromises: Promise<IdObjectSkeletonInterface>[] = [];
lookupPromises.push(
_getManagedObject({
type: 'teammember',
id,
fields: ['givenName', 'sn', 'userName'],
state,
})
);
lookupPromises.push(
_getManagedObject({
type: 'svcacct',
id,
fields: ['name', 'description'],
state,
})
);
lookupPromises.push(
_getManagedObject({
type: 'alpha_user',
id,
fields: ['givenName', 'sn', 'userName'],
state,
})
);
lookupPromises.push(
_getManagedObject({
type: 'bravo_user',
id,
fields: ['givenName', 'sn', 'userName'],
state,
})
);
const lookupResults = await Promise.allSettled(lookupPromises);
// tenant admin
if (lookupResults[0].status === 'fulfilled') {
const admin = lookupResults[0].value;
return `Admin user: ${admin.givenName} ${admin.sn} (${admin.userName})`;
}
// service account
if (lookupResults[1].status === 'fulfilled') {
const sa = lookupResults[1].value;
return `Service account: ${sa.name} (${sa.description})`;
}
// alpha user
if (lookupResults[2].status === 'fulfilled') {
const user = lookupResults[2].value;
return `Alpha user: ${user.givenName} ${user.sn} (${user.userName})`;
}
// bravo user
if (lookupResults[3].status === 'fulfilled') {
const user = lookupResults[3].value;
return `Bravo user:${user.givenName} ${user.sn} (${user.userName})`;
}
} else {
const user = await _getManagedObject({
type: 'user',
id,
fields: ['givenName', 'sn', 'userName'],
state,
});
return `${user.givenName} ${user.sn} (${user.userName})`;
}
} catch (error) {
// ignore
}
return id;
}

0 comments on commit 1a4192a

Please sign in to comment.