I don't know if I did good, but in the end I came up with this:
These are Janrain specific interfaces:
interface JanrainAuthenticationInterface {
public function getAccessToken(array $params);
public function getAuthorizationCode(array $params);
public function getCreationToken(array $params);
public function getVerificationCode(array $params);
public function useVerificationCode($verificationCode);
public function authNative(array $params);
public function authNativeTraditional(array $params);
public function linkAccount(array $params);
public function registerNative(array $params);
public function registerNativeTraditional(array $params);
public function token(array $params);
public function verifyEmailNative($params);
public function forgotPasswordNative($params);
}
interface JanrainEntityInterface {
public function count($entityType, $filter = '');
public function create(array $params);
public function bulkCreate(array $params);
public function delete($uuid, array $params = []);
public function deleteById($id, array $params = []);
public function deleteByAttribute($attributeKey, $attributeValue, array $params);
public function bulkDelete(array $params);
public function find(array $params);
public function purge($entityType, $commit = false);
public function replace($uuid, array $params);
public function replaceById($id, array $params);
public function replaceByAttribute($attributeKey, $attributeValue, array $params);
public function update($uuid, array $params);
public function updateById($id, array $params);
public function updateByAttribute($attributeKey, $attributeValue, array $params);
}
interface JanrainClientInterface extends JanrainEntityInterface, JanrainAuthenticationInterface {
public function getCurrentLocale();
public function setCurrentLocale($localeName);
public function getLocales();
}
These are provider agnostic interfaces:
interface AuthenticationProviderInterface {
public function authenticate($username, $password);
}
interface OauthProviderInterface {
public function getAccessToken(array $params);
public function getAuthorizationCode(array $params);
public function getCreationToken(array $params);
public function getVerificationCode(array $params);
public function useVerificationCode($verificationCode);
public function authenticate(array $params);
public function linkAccount(array $params);
public function register(array $params);
public function registerNativeTraditional(array $params);
public function token(array $params);
}
interface UserEmailerInterface {
public function sendVerificationEmail($userId, array $extraParams = []);
public function sendPasswordRecoveryEmail($userId, array $extraParams = []);
}
interface UserProviderInterface {
public function count($entityType, $filter = '');
public function create(array $params);
public function bulkCreate(array $params);
public function delete($uuid, array $params = []);
public function deleteById($id, array $params = []);
public function deleteByAttribute($attributeKey, $attributeValue, array $params);
public function bulkDelete(array $params);
public function find(array $params);
public function purge($entityType, $commit = false);
public function replace($uuid, array $params);
public function replaceById($id, array $params);
public function replaceByAttribute($attributeKey, $attributeValue, array $params);
public function update($uuid, array $params);
public function updateById($id, array $params);
public function updateByAttribute($attributeKey, $attributeValue, array $params);
}
Then there are four Janrain services implementing the provider agnostic interfaces, for example:
class JanrainAuthenticationProvider implements AuthenticationProviderInterface {
protected $janrainClient;
public function __construct(JanrainClientInterface $janrainClient) {
$this->janrainClient = $janrainClient;
}
public function authenticate($username, $password) {
$params = [
'signInEmailAddress' => $username,
'currentPassword' => $password,
];
return $this->janrainClient->authNativeTraditional($params);
}
}
Then JanrainClient
implementing JanrainClientInterface
.
What I do is, is some kind of facade in the previous four services, relaying all calls to JanrainClient
, with little logic.
Then, UserManager
(Application Service, describing use cases) has a constructor where I inject those four services using provider agnostic interfaces:
class UserManager {
/** @var UserProviderInterface */
protected $userProvider;
/** @var AuthenticationProviderInterface */
protected $authenticationProvider;
/** @var OauthProviderInterface */
protected $oauthProvider;
/** @var UserEmailerInterface */
protected $userEmailer;
/**
* UserManager constructor.
* @param UserProviderInterface $userProvider
* @param AuthenticationProviderInterface $authenticationProvider
* @param OauthProviderInterface $oauthProvider
* @param UserEmailerInterface $userEmailer
*/
public function __construct(
UserProviderInterface $userProvider,
AuthenticationProviderInterface $authenticationProvider,
OauthProviderInterface $oauthProvider,
UserEmailerInterface $userEmailer
) {
$this->userProvider = $userProvider;
$this->authenticationProvider = $authenticationProvider;
$this->oauthProvider = $oauthProvider;
$this->userEmailer = $userEmailer;
}
public function getUserBy($criteria) {
// TODO: Implement
}
public function doTraditionalLogin($username, $password) {
$response = $this->authenticationProvider->authenticate($username, $password);
return $response;
}
}