-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
18 changed files
with
323 additions
and
400 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
destinations/airbyte-faros-destination/resources/source-specific-configs/okta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
{ | ||
"title": "Okta", | ||
"type": "object", | ||
"oneOf": [ | ||
{ | ||
"title": "Configuration", | ||
"type": "object", | ||
"properties": { | ||
"source_type": { | ||
"type": "string", | ||
"const": "Okta", | ||
"order": 0 | ||
}, | ||
"column_names_mapping": { | ||
"order": 1, | ||
"title": "Column Names Mapping", | ||
"description": "Mapping of column names in Okta profile to employee fields", | ||
"type": "object", | ||
"properties": { | ||
"start_date_column_name": { | ||
"title": "Start Date Column Name", | ||
"description": "Column name for employee start date", | ||
"type": "string", | ||
"default": "startDate", | ||
"order": 0 | ||
}, | ||
"full_name_column_name": { | ||
"title": "Full Name Column Name", | ||
"description": "Column name for employee full name", | ||
"type": "string", | ||
"default": "displayName", | ||
"order": 1 | ||
}, | ||
"first_name_column_name": { | ||
"title": "First Name Column Name", | ||
"description": "Column name for employee first name", | ||
"type": "string", | ||
"default": "firstName", | ||
"order": 2 | ||
}, | ||
"last_name_column_name": { | ||
"title": "Last Name Column Name", | ||
"description": "Column name for employee last name", | ||
"type": "string", | ||
"default": "lastName", | ||
"order": 3 | ||
}, | ||
"employee_id_column_name": { | ||
"title": "Employee ID Column Name", | ||
"description": "Column name for employee ID", | ||
"type": "string", | ||
"default": "employeeNumber", | ||
"order": 4 | ||
}, | ||
"manager_name_column_name": { | ||
"title": "Manager Name Column Name", | ||
"description": "Column name for manager name", | ||
"type": "string", | ||
"default": "manager", | ||
"order": 5 | ||
}, | ||
"manager_id_column_name": { | ||
"title": "Manager ID Column Name", | ||
"description": "Column name for manager ID", | ||
"type": "string", | ||
"default": "managerId", | ||
"order": 6 | ||
}, | ||
"team_id_column_name": { | ||
"title": "Team ID Column Name", | ||
"description": "Column name for team ID", | ||
"type": "string", | ||
"default": "departmentId", | ||
"order": 7 | ||
}, | ||
"team_name_column_name": { | ||
"title": "Team Name Column Name", | ||
"description": "Column name for team name", | ||
"type": "string", | ||
"default": "department", | ||
"order": 8 | ||
}, | ||
"termination_date_column_name": { | ||
"title": "Termination Date Column Name", | ||
"description": "Column name for termination date", | ||
"type": "string", | ||
"default": "endDate", | ||
"order": 9 | ||
}, | ||
"location_column_name": { | ||
"title": "Location Column Name", | ||
"description": "Column name for location", | ||
"type": "string", | ||
"default": "location", | ||
"order": 10 | ||
}, | ||
"email_column_name": { | ||
"title": "Email Column Name", | ||
"description": "Column name for email", | ||
"type": "string", | ||
"default": "email", | ||
"order": 11 | ||
}, | ||
"employee_type_column_name": { | ||
"title": "Employee Type Column Name", | ||
"description": "Column name for employee type", | ||
"type": "string", | ||
"default": "employeeType", | ||
"order": 12 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 0 additions & 26 deletions
26
destinations/airbyte-faros-destination/src/converters/okta-faros/groups.ts
This file was deleted.
Oops, something went wrong.
49 changes: 0 additions & 49 deletions
49
destinations/airbyte-faros-destination/src/converters/okta/groups.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
159 changes: 82 additions & 77 deletions
159
destinations/airbyte-faros-destination/src/converters/okta/users.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,98 @@ | ||
import {AirbyteRecord} from 'faros-airbyte-cdk'; | ||
import {Utils} from 'faros-js-client'; | ||
import {sortBy} from 'lodash'; | ||
|
||
import {DestinationModel, DestinationRecord} from '../converter'; | ||
import {DestinationModel, DestinationRecord, StreamContext} from '../converter'; | ||
import {Customreports} from '../workday/customreports'; | ||
import {EmployeeRecord} from '../workday/models'; | ||
import {OktaConverter} from './common'; | ||
import {User} from './models'; | ||
|
||
export class Users extends OktaConverter { | ||
readonly destinationModels: ReadonlyArray<DestinationModel> = [ | ||
'identity_Identity', | ||
'org_Department', | ||
'org_Employee', | ||
]; | ||
type ColumnNameMapping = { | ||
start_date_column_name?: string; | ||
full_name_column_name?: string; | ||
first_name_column_name?: string; | ||
last_name_column_name?: string; | ||
employee_id_column_name?: string; | ||
manager_name_column_name?: string; | ||
manager_id_column_name?: string; | ||
team_id_column_name?: string; | ||
team_name_column_name?: string; | ||
termination_date_column_name?: string; | ||
location_column_name?: string; | ||
email_column_name?: string; | ||
employee_type_column_name?: string; | ||
}; | ||
|
||
private seenDepartments = new Set<string>(); | ||
export interface OktaConfig { | ||
column_names_mapping?: ColumnNameMapping; | ||
} | ||
|
||
async convert( | ||
record: AirbyteRecord | ||
): Promise<ReadonlyArray<DestinationRecord>> { | ||
const source = this.streamName.source; | ||
const user = record.record.data as User; | ||
const profile = user.profile; | ||
const uid = user.id; | ||
const res: DestinationRecord[] = []; | ||
export class Users extends OktaConverter { | ||
private workdayConverter = new Customreports(); | ||
private _config: OktaConfig = undefined; | ||
|
||
const fullName = [profile.firstName, profile.middleName, profile.lastName] | ||
.filter((x) => x) | ||
.join(' '); | ||
private initialize(ctx: StreamContext): void { | ||
this._config = | ||
this._config ?? ctx.config.source_specific_configs?.okta ?? {}; | ||
} | ||
|
||
const joinedAt = | ||
Utils.toDate(profile.startDate) ?? Utils.toDate(user.created) ?? null; | ||
readonly destinationModels: ReadonlyArray<DestinationModel> = | ||
this.workdayConverter.destinationModels; | ||
|
||
const departments = sortBy( | ||
Object.entries(profile).filter(([k, v]) => | ||
k.toLowerCase().includes('department') | ||
), | ||
([k, v]) => k | ||
).map(([k, v]) => v); | ||
async convert( | ||
record: AirbyteRecord, | ||
ctx?: StreamContext | ||
): Promise<ReadonlyArray<DestinationRecord>> { | ||
this.initialize(ctx); | ||
const rec = record.record.data as User; | ||
const profile = rec.profile; | ||
|
||
const departmentUid = | ||
(departments.length > 0 ? departments[0] : null) ?? | ||
profile.department ?? | ||
null; | ||
const startDate = | ||
profile[this._config.column_names_mapping.start_date_column_name]; | ||
const fullName = | ||
profile[this._config.column_names_mapping.full_name_column_name]; | ||
const firstName = | ||
profile[this._config.column_names_mapping.first_name_column_name]; | ||
const lastName = | ||
profile[this._config.column_names_mapping.last_name_column_name]; | ||
const employeeId = | ||
profile[this._config.column_names_mapping.employee_id_column_name]; | ||
const managerName = | ||
profile[this._config.column_names_mapping.manager_name_column_name]; | ||
const managerId = | ||
profile[this._config.column_names_mapping.manager_id_column_name]; | ||
const teamId = | ||
profile[this._config.column_names_mapping.team_id_column_name]; | ||
const teamName = | ||
profile[this._config.column_names_mapping.team_name_column_name]; | ||
const terminationDate = | ||
profile[this._config.column_names_mapping.termination_date_column_name]; | ||
const location = | ||
profile[this._config.column_names_mapping.location_column_name]; | ||
const email = profile[this._config.column_names_mapping.email_column_name]; | ||
const employeeType = | ||
profile[this._config.column_names_mapping.employee_type_column_name]; | ||
|
||
if (departmentUid && !this.seenDepartments.has(departmentUid)) { | ||
this.seenDepartments.add(departmentUid); | ||
res.push({ | ||
model: 'org_Department', | ||
record: { | ||
uid: departmentUid, | ||
name: departmentUid, | ||
description: null, | ||
}, | ||
}); | ||
} | ||
const asWorkdayRecord: EmployeeRecord = { | ||
Start_Date: startDate, | ||
Full_Name: fullName ?? `${firstName} ${lastName}`, | ||
Employee_ID: employeeId, | ||
Manager_Name: managerName, | ||
Manager_ID: managerId, | ||
Team_ID: teamId, | ||
Team_Name: teamName, | ||
Termination_Date: terminationDate, | ||
Location: location, | ||
Email: email, | ||
Employee_Type: employeeType, | ||
}; | ||
|
||
res.push( | ||
{ | ||
model: 'identity_Identity', | ||
record: { | ||
uid, | ||
firstName: profile.firstName, | ||
lastName: profile.lastName, | ||
fullName, | ||
photoUrl: null, | ||
primaryEmail: profile.email, | ||
emails: [profile.email], | ||
createdAt: null, | ||
updatedAt: null, | ||
}, | ||
}, | ||
{ | ||
model: 'org_Employee', | ||
record: { | ||
uid, | ||
title: profile.title, | ||
level: null, | ||
joinedAt, | ||
terminatedAt: null, | ||
department: departmentUid ? {uid: departmentUid} : null, | ||
identity: {uid, source}, | ||
manager: profile.manager ? {uid: profile.manager, source} : null, | ||
reportingChain: null, // TODO: compute reporting chain | ||
location: null, // TODO: lookup location | ||
source, | ||
}, | ||
} | ||
); | ||
record.record.data = asWorkdayRecord; | ||
return this.workdayConverter.convert(record, ctx); | ||
} | ||
|
||
return res; | ||
async onProcessingComplete( | ||
ctx: StreamContext | ||
): Promise<ReadonlyArray<DestinationRecord>> { | ||
return this.workdayConverter.onProcessingComplete(ctx); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
destinations/airbyte-faros-destination/test/__snapshots__/index.test.ts.snap
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.