-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(service): users/auth: move local idp app layer operations to…
… internal services to allow dependency injection and reuse
- Loading branch information
Showing
7 changed files
with
99 additions
and
78 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
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 was deleted.
Oops, something went wrong.
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
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,15 @@ | ||
import { LocalIdpAccount, LocalIdpAuthenticationResult, LocalIdpCredentials, LocalIdpError } from './local-idp.entities' | ||
|
||
|
||
export interface MageLocalIdentityProviderService { | ||
createAccount(credentials: LocalIdpCredentials): Promise<LocalIdpAccount | LocalIdpError> | ||
/** | ||
* Return `null` if no account for the given username exists. | ||
*/ | ||
deleteAccount(username: string): Promise<LocalIdpAccount | null> | ||
/** | ||
* Return `null` if no account for the given username exists. If authentication fails, update the corresponding | ||
* account according to the service's account lock policy. | ||
*/ | ||
authenticate(credentials: LocalIdpCredentials): Promise<LocalIdpAuthenticationResult | null> | ||
} |
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,55 @@ | ||
import { attemptAuthentication, LocalIdpAccount, LocalIdpAuthenticationResult, LocalIdpCredentials, LocalIdpDuplicateUsernameError, LocalIdpError, LocalIdpInvalidPasswordError, LocalIdpRepository, prepareNewAccount } from './local-idp.entities' | ||
import { MageLocalIdentityProviderService } from './local-idp.services.api' | ||
|
||
|
||
export function createLocalIdentityProviderService(repo: LocalIdpRepository): MageLocalIdentityProviderService { | ||
|
||
async function createAccount(credentials: LocalIdpCredentials): Promise<LocalIdpAccount | LocalIdpError> { | ||
const securityPolicy = await repo.readSecurityPolicy() | ||
const { username, password } = credentials | ||
const candidateAccount = await prepareNewAccount(username, password, securityPolicy) | ||
if (candidateAccount instanceof LocalIdpInvalidPasswordError) { | ||
return candidateAccount | ||
} | ||
const createdAccount = await repo.createLocalAccount(candidateAccount) | ||
if (createdAccount instanceof LocalIdpError) { | ||
if (createdAccount instanceof LocalIdpDuplicateUsernameError) { | ||
console.error(`attempted to create local account with duplicate username ${username}`, createdAccount) | ||
} | ||
return createdAccount | ||
} | ||
return createdAccount | ||
} | ||
|
||
function deleteAccount(username: string): Promise<LocalIdpAccount | null> { | ||
return repo.deleteLocalAccount(username) | ||
} | ||
|
||
async function authenticate(credentials: LocalIdpCredentials): Promise<LocalIdpAuthenticationResult | null> { | ||
const { username, password } = credentials | ||
const account = await repo.readLocalAccount(username) | ||
if (!account) { | ||
console.info('local account does not exist:', username) | ||
return null | ||
} | ||
const securityPolicy = await repo.readSecurityPolicy() | ||
const attempt = await attemptAuthentication(account, password, securityPolicy.accountLock) | ||
if (attempt.failed) { | ||
console.info('local authentication failed', attempt.failed) | ||
return attempt | ||
} | ||
const accountSaved = await repo.updateLocalAccount(attempt.authenticated) | ||
if (accountSaved) { | ||
attempt.authenticated = accountSaved | ||
return attempt | ||
} | ||
console.error(`account for username ${username} did not exist for update after authentication attempt`) | ||
return null | ||
} | ||
|
||
return { | ||
createAccount, | ||
deleteAccount, | ||
authenticate, | ||
} | ||
} |