-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from agiledigital-labs/feature/IE-9
IE-9 added support for deleting users
- Loading branch information
Showing
5 changed files
with
171 additions
and
16 deletions.
There are no files selected for viewing
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,13 +1,17 @@ | ||
# Oktagon CLI interface | ||
|
||
This is a project to aid in the interaction with Okta. | ||
CLI tools for managing users in Okta. | ||
|
||
_Only use this tool in non-production environments, because it will bypass any MFA requirements of the organisation AND break the audit log that you would otherwise get in Okta._ | ||
|
||
### Node usage | ||
|
||
After compilation using the `npm run build` command, run all commands using `./dist/oktagon <Command name>`. | ||
|
||
### Command: list-users | ||
### Common parameters | ||
|
||
All `oktagon` commands require connecting to the Okta management APIs. The recommended way of doing this is to create an API-only application using the Admin console. The tool currently only supports private key authentication. | ||
|
||
Provides a list of all users' logins, emails, display names, and statuses. Allows for environment variables under the name `OKTAGON_PK`, `OKTAGON_PRIVATE_KEY`, `OKTAGON_CID`, `OKTAGON_CLIENT_ID`. The environment variables correspond to the arguments `--pk`, `--private-key`, `--cid`, and `--client-id` respectively. | ||
Allows for environment variables under the name `OKTAGON_PK`, `OKTAGON_PRIVATE_KEY`, `OKTAGON_CID`, `OKTAGON_CLIENT_ID`. The environment variables correspond to the arguments `--pk`, `--private-key`, `--cid`, and `--client-id` respectively. | ||
|
||
The operation will only work if you have provided the correct client ID (in string form) and private key (in string form, must be JWT format e.g -pk "{JWK}"). |
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
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,105 @@ | ||
import { UserStatus, User as OktaUser } from '@okta/okta-sdk-nodejs'; | ||
import { Argv } from 'yargs'; | ||
import { RootCommand } from '..'; | ||
|
||
import { | ||
oktaManageClient, | ||
OktaConfiguration, | ||
oktaUserAsUser, | ||
User, | ||
getUser, | ||
} from './services/user-service'; | ||
|
||
const deleteUser = async ( | ||
oktaConfiguration: OktaConfiguration, | ||
userId: string | ||
): Promise<User> => { | ||
const client = oktaManageClient(oktaConfiguration); | ||
|
||
const maybeOktaUser = await getUser(userId, client); | ||
|
||
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types | ||
const performDelete = async (oktaUser: OktaUser) => { | ||
// eslint-disable-next-line functional/no-expression-statement | ||
await oktaUser.delete({ | ||
sendEmail: false, | ||
}); | ||
|
||
return oktaUserAsUser(oktaUser); | ||
}; | ||
|
||
// eslint-disable-next-line functional/functional-parameters | ||
const throwOnNotDeprovisioned = () => { | ||
// eslint-disable-next-line functional/no-throw-statement | ||
throw new Error( | ||
`User [${userId}] has not been deprovisioned. Deprovision before deleting.` | ||
); | ||
}; | ||
|
||
// eslint-disable-next-line functional/functional-parameters | ||
const throwOnMissing = () => { | ||
// eslint-disable-next-line functional/no-throw-statement | ||
throw new Error(`User [${userId}] does not exist. Can not delete.`); | ||
}; | ||
|
||
return maybeOktaUser === undefined | ||
? throwOnMissing() | ||
: maybeOktaUser.status === UserStatus.DEPROVISIONED | ||
? performDelete(maybeOktaUser) | ||
: throwOnNotDeprovisioned(); | ||
}; | ||
|
||
export default ( | ||
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types | ||
rootCommand: RootCommand | ||
): Argv<{ | ||
readonly clientId: string; | ||
readonly privateKey: string; | ||
readonly organisationUrl: string; | ||
readonly userId: string; | ||
}> => | ||
rootCommand.command( | ||
'delete-user [user-id]', | ||
'Deletes the specified user', | ||
// eslint-disable-next-line functional/no-return-void, @typescript-eslint/prefer-readonly-parameter-types | ||
(yargs) => { | ||
// eslint-disable-next-line functional/no-expression-statement | ||
yargs.positional('user-id', { | ||
describe: 'the identifier of the user to delete', | ||
type: 'string', | ||
demandOption: true, | ||
}); | ||
}, | ||
async (args: { | ||
readonly clientId: string; | ||
readonly privateKey: string; | ||
readonly organisationUrl: string; | ||
readonly userId: string; | ||
}) => { | ||
// eslint-disable-next-line functional/no-try-statement | ||
try { | ||
const user = await deleteUser( | ||
{ | ||
...args, | ||
}, | ||
args.userId | ||
); | ||
// eslint-disable-next-line functional/no-expression-statement | ||
console.info(`Deleted [${user.id}] [${user.email}].`); | ||
} catch (error: unknown) { | ||
// eslint-disable-next-line functional/no-throw-statement | ||
throw error instanceof Error | ||
? new Error( | ||
`Failed to delete user [${args.userId}] in [${args.organisationUrl}].`, | ||
{ | ||
cause: error, | ||
} | ||
) | ||
: new Error( | ||
`Failed to delete user [${args.userId}] in [${ | ||
args.organisationUrl | ||
}] because of [${JSON.stringify(error)}].` | ||
); | ||
} | ||
} | ||
); |
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
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