okta-mcp-server
Version:
Model Context Protocol (MCP) server for Okta API operations with support for bulk operations and caching
297 lines • 10.5 kB
JavaScript
import { faker } from '@faker-js/faker';
export class PolicyGenerator {
faker;
statusDistribution;
policyTypes;
generatedCount = 0;
generatedNames = new Set();
priorityCounter = 1;
constructor(options = {}) {
this.faker = faker;
if (options.seed) {
this.faker.seed(options.seed);
}
this.statusDistribution = options.statusDistribution || {
ACTIVE: 0.85,
INACTIVE: 0.15,
};
this.policyTypes = options.policyTypes || [
'OKTA_SIGN_ON',
'PASSWORD',
'MFA_ENROLL',
'IDP_DISCOVERY',
'PROFILE_ENROLLMENT',
];
}
generate() {
this.generatedCount++;
const id = `00p${this.faker.string.alphanumeric(17)}`;
const type = this.faker.helpers.arrayElement(this.policyTypes);
const created = this.faker.date.past({ years: 2 });
const lastUpdated = this.faker.date.between({ from: created, to: new Date() });
const status = this.selectStatus();
const { name, description } = this.generateNameAndDescription(type);
const system = this.faker.datatype.boolean({ probability: 0.1 });
const priority = system ? 99 : this.priorityCounter++;
const policy = {
id,
status,
name,
description,
priority,
system,
created: created.toISOString(),
lastUpdated: lastUpdated.toISOString(),
type,
};
// Add type-specific conditions and settings
this.addPolicySpecificProperties(policy, type);
return policy;
}
generateBatch(count) {
return Array.from({ length: count }, () => this.generate());
}
selectStatus() {
const random = this.faker.number.float({ min: 0, max: 1 });
let cumulative = 0;
for (const [status, probability] of Object.entries(this.statusDistribution)) {
cumulative += probability;
if (random <= cumulative) {
return status;
}
}
return 'ACTIVE';
}
generateNameAndDescription(type) {
let name;
let description;
switch (type) {
case 'OKTA_SIGN_ON':
name = this.generateUniqueName([
'Default Sign On Policy',
'Corporate Network Access',
'Remote Access Policy',
'High Security Sign On',
'Partner Access Policy',
'Contractor Sign On Policy',
]);
description = `Sign-on policy for ${name.toLowerCase()}`;
break;
case 'PASSWORD':
name = this.generateUniqueName([
'Default Password Policy',
'Strong Password Policy',
'Admin Password Policy',
'Service Account Password Policy',
'Legacy System Password Policy',
]);
description = `Password requirements for ${name.toLowerCase()}`;
break;
case 'MFA_ENROLL':
name = this.generateUniqueName([
'Default MFA Policy',
'Executive MFA Requirements',
'Developer MFA Policy',
'Required MFA Enrollment',
'Optional MFA Enrollment',
]);
description = `Multi-factor authentication enrollment policy`;
break;
case 'IDP_DISCOVERY':
name = this.generateUniqueName([
'Default IDP Discovery',
'Domain-based Routing',
'Email Domain Discovery',
'Corporate IDP Selection',
]);
description = `Identity provider discovery and routing policy`;
break;
case 'PROFILE_ENROLLMENT':
name = this.generateUniqueName([
'Default Profile Enrollment',
'Self-Service Registration',
'Progressive Profiling',
'Employee Onboarding',
]);
description = `Profile enrollment and registration policy`;
break;
default:
name = this.generateUniqueName([`${type} Policy`]);
description = `Policy for ${type}`;
}
return { name, description };
}
generateUniqueName(options) {
let name;
let attempts = 0;
const maxAttempts = 100;
do {
name = this.faker.helpers.arrayElement(options);
// Add environment or group suffix sometimes
if (this.faker.datatype.boolean({ probability: 0.3 })) {
const suffix = this.faker.helpers.arrayElement([
'Production',
'Development',
'Staging',
'US Region',
'EU Region',
'APAC Region',
]);
name = `${name} - ${suffix}`;
}
attempts++;
if (attempts >= maxAttempts) {
name = `${name}_${this.faker.string.alphanumeric(6)}`;
break;
}
} while (this.generatedNames.has(name));
this.generatedNames.add(name);
return name;
}
addPolicySpecificProperties(policy, type) {
// Add common conditions
policy.conditions = {
people: {
users: {
exclude: [],
include: ['EVERYONE'],
},
groups: {
exclude: [],
include: [],
},
},
};
// Add type-specific properties
switch (type) {
case 'OKTA_SIGN_ON':
policy.conditions['network'] = {
connection: 'ANYWHERE',
};
policy.conditions['authContext'] = {
authType: 'ANY',
};
policy.settings = {
factors: {
password: {},
okta_password: {},
},
session: {
maxSessionIdleMinutes: 120,
maxSessionLifetimeMinutes: 720,
usePersistentCookie: false,
},
};
break;
case 'PASSWORD':
policy.settings = {
password: {
complexity: {
minLength: 8,
minLowerCase: 1,
minUpperCase: 1,
minNumber: 1,
minSymbol: 0,
excludeUsername: true,
excludeAttributes: ['firstName', 'lastName'],
},
age: {
maxAgeDays: 90,
expireWarnDays: 14,
minAgeMinutes: 0,
historyCount: 5,
},
lockout: {
maxAttempts: 5,
autoUnlockMinutes: 30,
showLockoutFailures: true,
},
},
};
break;
case 'MFA_ENROLL':
policy.settings = {
factors: {
okta_verify: {
enroll: {
self: 'OPTIONAL',
},
consent: {
type: 'NONE',
},
},
okta_sms: {
enroll: {
self: 'OPTIONAL',
},
consent: {
type: 'NONE',
},
},
okta_email: {
enroll: {
self: 'REQUIRED',
},
consent: {
type: 'NONE',
},
},
},
};
break;
case 'IDP_DISCOVERY':
policy.conditions['userIdentifier'] = {
patterns: [
{
matchType: 'SUFFIX',
value: '@example.com',
},
],
type: 'IDENTIFIER',
};
policy.settings = {
idp: {
providers: [],
},
};
break;
case 'PROFILE_ENROLLMENT':
policy.settings = {
profileAttributes: {
required: [],
optional: ['firstName', 'lastName', 'email'],
},
registration: {
activationRequirements: {
emailVerification: true,
},
},
};
break;
}
// Add some random additional conditions
if (this.faker.datatype.boolean({ probability: 0.4 })) {
policy.conditions['platform'] = {
include: [
{
type: 'ANY',
},
],
};
}
if (this.faker.datatype.boolean({ probability: 0.3 })) {
policy.conditions['risk'] = {
behaviors: ['ANOMALOUS_LOCATION', 'ANOMALOUS_DEVICE'],
};
}
}
reset() {
this.generatedCount = 0;
this.generatedNames.clear();
this.priorityCounter = 1;
}
getGeneratedCount() {
return this.generatedCount;
}
}
//# sourceMappingURL=policy-generator.js.map