webiik/account

The Account provides common interface for user authentication.

1.2 2020-04-10 14:27 UTC

This package is auto-updated.

Last update: 2024-11-11 00:59:56 UTC


README

Account

The Account provides common interface for user authentication.

Installation

composer require webiik/account

Example

The following example expects you have already written your account implementation and you use email and password for user authentication.

$account = new \Webiik\Account\Account();

// Add your account implementation
$account->addAccount('YourAccount', function () {
	return new \Webiik\Service\YourAccount());
});

// Use one of your account implementations
$account->useAccount('YourAccount');

// Try authenticate a user
try {
    $user = $this->account->auth([
        'email' => 'kitty@webiik.com',
        'password' => 'meow!'
    ]);
    echo 'User ID: ' . $user->getId() . '<br/>';
    echo 'User status: ' . $user->getStatus() . '<br/>';
    echo 'User role: ' . $user->getRole() . '<br/>';
    
    if ($user->hasRole('admin')) {
        // Do something...
    }

} catch (AccountException $e) {
    echo $e->getMessage() . '<br/>';
    print_r($e->getValidationResult());
}

Settings

addAccount

addAccount(string $name, callable $accountFactory): void

addAccount() adds an implementation of account.

$account->addAccount('YourAccount', function () {
	return new \Webiik\Service\YourAccount());
});

useAccount

useAccount(string $name): void

useAccount() sets account to be used when calling custom account related methods.

$account->useAccount('YourAccount');

setNamespace

setNamespace(string $namespace): void

setNamespace() sets authentication namespace. It allows you to use separate authentication for different parts of your application. If you don't set any namespace, it means user belongs to default namespace.

// Set namespace to 'en'
$account->setNamespace('en');

// Let's say, user 'kitty@webiik.com' is authenticated in
// namespace 'es', so the following authentication fails.
try {
    $user = $this->account->auth([
        'email' => 'kitty@webiik.com',
        'password' => 'meow!'
    ]);   
} catch (AccountException $e) {
    echo $e->getMessage(); // e.g. Account does not exist.
}

Writing Your Custom Account

To write your account implementation you have to extend from abstract class AccountBase and write your own implementation of methods auth, signup, update, disable, delete, createToken, activate and resetPassword. Don't forget to incorporate authentication namespace to each method. Read below intended function of each mentioned method and adapt your implementation to it.

auth

auth(array $credentials): User

auth() authenticates a user with credentials. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_CREDENTIAL, INVALID_PASSWORD, ACCOUNT_DOES_NOT_EXIST, ACCOUNT_IS_NOT_ACTIVATED, ACCOUNT_IS_BANNED, ACCOUNT_IS_DISABLED, FAILURE

try {
    $user = $this->account->auth([
        'email' => 'kitty@webiik.com',
        'password' => 'meow!'
    ]);   
} catch (AccountException $e) {
    echo $e->getMessage();
}

To compare passwords, always use secure method verifyPassword(string $password, string $hash): bool provided by AccountBase.

reAuth

reAuth(string $uid): User

reAuth() re-authenticates a user by unique user identifier uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, ACCOUNT_IS_NOT_ACTIVATED, ACCOUNT_IS_BANNED, ACCOUNT_IS_DISABLED, FAILURE

try {
    $user = $this->account->reAuth('d4rjke8');
} catch (AccountException $e) {
    echo $e->getMessage();
}

signup

signup(array $credentials): User

signup() signs up a user with credentials. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_CREDENTIAL, ACCOUNT_ALREADY_EXISTS, FAILURE

try {
    $user = $this->account->signup([
        'email' => 'kitty@webiik.com',
        'password' => 'meow!'
    ]);   
} catch (AccountException $e) {
    echo $e->getMessage();
}

Never store passwords in plain text. AccountBase provides you secure method to hash passwords hashPassword(string $password): string.

update

update(int $uid, array $data): User

update() updates data on account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, INVALID_KEY, FAILURE

try {
    $user = $this->account->update(1, [
    	'email' => 'nyan@webiik.com',
    ]);   
} catch (AccountException $e) {
    echo $e->getMessage();
}

disable

disable(int $uid, int $reason, array $data = []): User

disable() sets account status to ACCOUNT_IS_DISABLED or ACCOUNT_IS_BANNED on account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, FAILURE

try {
    $user = $this->account->disable(1, \Webiik\Account\AccountBase::ACCOUNT_IS_BANNED);   
} catch (AccountException $e) {
    echo $e->getMessage();
}

delete

delete(int $uid, array $data = []): User

delete() deletes an account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, FAILURE

try {
    $user = $this->account->delete([
        'uid' => 1,       
    ]);   
} catch (AccountException $e) {
    echo $e->getMessage();
}

createToken

createToken(): string

createToken() creates and returns time limited security token. On error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, FAILURE

try {
    $token = $this->account->createToken();
    
    // Send token to user, so he can perform an action...
     
} catch (AccountException $e) {
    echo $e->getMessage();
}

activate

activate(string $token): User

activate() activates an account by valid token. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_TOKEN, FAILURE

try {
    $user = $this->account->activate($token);
} catch (AccountException $e) {
    echo $e->getMessage();
}

resetPassword

resetPassword(string $token, string $password): User

resetPassword() updates account password by valid token. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_TOKEN, FAILURE

try {
    $user = $this->account->resetPassword($token, 'new-password');
} catch (AccountException $e) {
    echo $e->getMessage();
}

Never store passwords in plain text. AccountBase provides you secure method to hash passwords hashPassword(string $password): string.

User

User is an object returned by several Account methods. User provides handy methods to work with authenticated user.

__construct

__construct(int $status, $id, string $role = '', array $info = [])

__construct() creates User object.

Parameters

  • status user account status. Usual status codes are: ACCOUNT_IS_OK and ACCOUNT_IS_NOT_ACTIVATED
  • id unique user account id.
  • role (optional) user role.
  • info (optional) additional user account info.
$user = new User(self::ACCOUNT_IS_OK, 1, 'user');

getId

getId()

getId() returns unique user account id.

$uid = $user->getId();

getRole

getRole(): string

getRole() returns user role.

$role = $user->getRole();

hasRole

hasRole(string $role): bool

hasRole() checks if user has given role.

if ($user->hasRole('user') {
    // Do something...
}

getInfo

getInfo(): array

getInfo() returns additional user account info.

$info = $user->getInfo();

needsActivation

needsActivation(): bool

needsActivation() checks if user account requires activation.

if ($user->needsActivation()) {
    // Send activation to user email
}

Account Exception

AccountException has to be thrown by all implemented account methods. Unlike standard Exception, AccountException has one extra parameter validationResult. This parameter is intended to store invalid credentials in the following format e.g. ['email' => ['Invalid email'], 'password' => ['Password is too short.']]

__construct

__construct($message = '', $code = 0, \Throwable $previous = null, array $validationResult = [])

__construct() creates AccountException object.

throw new AccountException(self::MSG_INVALID_CREDENTIAL, self::INVALID_CREDENTIAL, null, ['email' => ['Invalid email'], 'password' => ['Password is too short.']]);

getValidationResult

getValidationResult(): array

getValidationResult() returns invalid credentials.

try {
    $user = $this->account->auth([
        'email' => 'kitty@webiik.com',
        'password' => 'meow!'
    ]);   
} catch (AccountException $e) {
    print_r($e->getValidationResult()); // e.g. ['email' => ['Invalid email'], 'password' => ['Password is too short.']]
}

Resources