Completed
Push — ezp_30797 ( 8198f2...1e476a )
by
unknown
18:51
created

Provider::createSecurityUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the user Provider class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\MVC\Symfony\Security\User;
10
11
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
12
use eZ\Publish\API\Repository\Repository;
13
use eZ\Publish\Core\MVC\Symfony\Security\User;
14
use eZ\Publish\Core\MVC\Symfony\Security\UserInterface;
15
use eZ\Publish\Core\MVC\Symfony\Security\ReferenceUserInterface;
16
use eZ\Publish\API\Repository\Values\User\User as APIUser;
17
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
18
use Symfony\Component\Security\Core\User\UserInterface as CoreUserInterface;
19
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
20
21
class Provider implements APIUserProviderInterface
22
{
23
    /** @var \eZ\Publish\API\Repository\Repository */
24
    protected $repository;
25
26
    /**
27
     * @param \eZ\Publish\API\Repository\Repository $repository
28
     */
29
    public function __construct(Repository $repository)
30
    {
31
        $this->repository = $repository;
32
    }
33
34
    /**
35
     * Loads the user for the given user ID.
36
     * $user can be either the user ID or an instance of \eZ\Publish\Core\MVC\Symfony\Security\User
37
     * (anonymous user we try to check access via SecurityContext::isGranted()).
38
     *
39
     * @param string|\eZ\Publish\Core\MVC\Symfony\Security\User $user Either the user ID to load an instance of User object. A value of -1 represents an anonymous user.
40
     *
41
     * @return \eZ\Publish\Core\MVC\Symfony\Security\UserInterface
42
     *
43
     * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException if the user is not found
44
     */
45
    public function loadUserByUsername($user)
46
    {
47
        try {
48
            // SecurityContext always tries to authenticate anonymous users when checking granted access.
49
            // In that case $user is an instance of \eZ\Publish\Core\MVC\Symfony\Security\User.
50
            // We don't need to reload the user here.
51
            if ($user instanceof UserInterface) {
52
                return $user;
53
            }
54
55
            return $this->createSecurityUser(
56
                $this->repository->getUserService()->loadUserByLogin($user)
57
            );
58
        } catch (NotFoundException $e) {
59
            throw new UsernameNotFoundException($e->getMessage(), 0, $e);
60
        }
61
    }
62
63
    /**
64
     * Refreshes the user for the account interface.
65
     *
66
     * It is up to the implementation to decide if the user data should be
67
     * totally reloaded (e.g. from the database), or if the UserInterface
68
     * object can just be merged into some internal array of users / identity
69
     * map.
70
     *
71
     * @param \Symfony\Component\Security\Core\User\UserInterface $user
72
     *
73
     * @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException
74
     *
75
     * @return \Symfony\Component\Security\Core\User\UserInterface
76
     */
77
    public function refreshUser(CoreUserInterface $user)
78
    {
79
        if (!$user instanceof UserInterface) {
80
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
81
        }
82
83
        try {
84
            $refreshedAPIUser = $this->repository->getUserService()->loadUser(
85
                $user instanceof ReferenceUserInterface ?
86
                $user->getAPIUserReference()->getUserId() :
87
                $user->getAPIUser()->id
88
            );
89
            $user->setAPIUser($refreshedAPIUser);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\MVC\Symf...Interface::setAPIUser() has been deprecated with message: Will be replaced by {@link ReferenceUserInterface::getAPIUser()}, adding LogicException to signature.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
90
            $this->repository->setCurrentUser($refreshedAPIUser);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
91
92
            return $user;
93
        } catch (NotFoundException $e) {
94
            throw new UsernameNotFoundException($e->getMessage(), 0, $e);
95
        }
96
    }
97
98
    /**
99
     * Whether this provider supports the given user class.
100
     *
101
     * @param string $class
102
     *
103
     * @return bool
104
     */
105
    public function supportsClass($class)
106
    {
107
        $supportedClass = 'eZ\\Publish\\Core\\MVC\\Symfony\\Security\\User';
108
109
        return $class === $supportedClass || is_subclass_of($class, $supportedClass);
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if $supportedClass can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
110
    }
111
112
    /**
113
     * Loads a regular user object, usable by Symfony Security component, from a user object returned by Public API.
114
     *
115
     * @param \eZ\Publish\API\Repository\Values\User\User $apiUser
116
     *
117
     * @return \eZ\Publish\Core\MVC\Symfony\Security\User
118
     */
119
    public function loadUserByAPIUser(APIUser $apiUser)
120
    {
121
        return $this->createSecurityUser($apiUser);
122
    }
123
124
    /**
125
     * Creates user object, usable by Symfony Security component, from a user object returned by Public API.
126
     *
127
     * @param \eZ\Publish\API\Repository\Values\User\User $apiUser
128
     *
129
     * @return \eZ\Publish\Core\MVC\Symfony\Security\User
130
     */
131
    private function createSecurityUser(APIUser $apiUser): User
132
    {
133
        $isPasswordExpired = $this->repository->getUserService()->getPasswordInfo($apiUser)->isPasswordExpired();
134
135
        return new User(
136
            $apiUser,
137
            ['ROLE_USER'],
138
            !$isPasswordExpired
139
        );
140
    }
141
}
142