authenticate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 17
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date 30-12-2018
5
 *
6
 * This is similar to the PersistingAuthenticator version but is user aware.
7
 * Meaning this can be used to link third party connections while the user is logged in. (user aware).
8
 * use this if you want to connect & use multiple vendor logins such as Facebook and/or Google while logged in.
9
 */
10
11
namespace TSK\SSO\Auth;
12
13
use TSK\SSO\AppUser\AppUser;
14
use TSK\SSO\AppUser\ExistingAppUser;
15
use TSK\SSO\Storage\Exception\DataCannotBeStoredException;
16
use TSK\SSO\Storage\FileSystemThirdPartyStorageRepository;
17
use TSK\SSO\Storage\ThirdPartyStorageRepository;
18
use TSK\SSO\ThirdParty\Exception\NoThirdPartyEmailFoundException;
19
use TSK\SSO\ThirdParty\Exception\ThirdPartyConnectionFailedException;
20
use TSK\SSO\ThirdParty\VendorConnection;
21
22
/**
23
 * @package TSK\SSO\Auth
24
 * @see PersistingAuthenticator
25
 *
26
 * Use this to validate and connect other accounts belong to the same vendor.
27
 * You need to use PersistingAuthenticator when the user is NOT logged in yet.
28
 *
29
 * ex: A user can have three(3) Google Mail accounts.
30
 *
31
 * You may want to let users connect the rest of their account while they are LOGGED IN (aka user aware).
32
 */
33
class AppUserAwarePersistingAuthenticator implements Authenticator
34
{
35
    /**
36
     * @var AppUser
37
     */
38
    private $appUser;
39
40
    /**
41
     * @var ThirdPartyStorageRepository
42
     */
43
    private $storageRepository;
44
45
    /**
46
     * @param AppUser $appUser client application user which can be used to connect multiple other vendor accounts.
47
     * @param ThirdPartyStorageRepository $storageRepository a storage implementation to store the third party auth
48
     *        data. By default uses file system as the storage.
49
     */
50 1
    public function __construct(AppUser $appUser, ThirdPartyStorageRepository $storageRepository = null)
51
    {
52 1
        $this->appUser = $appUser;
53 1
        $this->storageRepository = is_null($storageRepository)
54 1
            ? new FileSystemThirdPartyStorageRepository()
55
            : $storageRepository;
56 1
    }
57
58
    /**
59
     * This will try to authenticate a user using any given vendor connection.
60
     * Upon a successful attempt, returns the authenticated user.
61
     *
62
     * @param VendorConnection $thirdPartyConnection vendor connection to use to perform an auth
63
     * @return AppUser
64
     *
65
     * @throws DataCannotBeStoredException
66
     * @throws NoThirdPartyEmailFoundException
67
     * @throws ThirdPartyConnectionFailedException
68
     */
69 1
    public function authenticate(VendorConnection $thirdPartyConnection)
70
    {
71 1
        $accessToken = $thirdPartyConnection->grantNewAccessToken();
72
73 1
        $thirdPartyUser = $thirdPartyConnection->getSelf($accessToken);
74
75
        /**
76
         * Resolving a new app user by taking
77
         *  - the known user's application id
78
         *  - and the incoming new vendor account's email
79
         */
80 1
        $derivedAppUser = new ExistingAppUser($this->appUser->id(), $thirdPartyUser->email());
81
82
        // Let's store this new third party user mapping against the existing user
83 1
        $this->storageRepository->save($derivedAppUser, $thirdPartyUser, $accessToken);
84
85 1
        return $derivedAppUser;
86
    }
87
}
88