Passed
Pull Request — master (#24)
by Damian
01:50
created

getCustomAuthenticators()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Firesphere\GraphQLJWT\Mutations;
4
5
use App\Users\GraphQL\Types\TokenStatusEnum;
6
use Firesphere\GraphQLJWT\Extensions\MemberExtension;
7
use Firesphere\GraphQLJWT\Helpers\MemberTokenGenerator;
8
use Firesphere\GraphQLJWT\Helpers\RequiresAuthenticator;
9
use Generator;
10
use GraphQL\Type\Definition\ResolveInfo;
11
use GraphQL\Type\Definition\Type;
12
use Psr\Container\NotFoundExceptionInterface;
13
use SilverStripe\Control\Controller;
14
use SilverStripe\Control\HTTPRequest;
15
use SilverStripe\Core\Extensible;
16
use SilverStripe\GraphQL\MutationCreator;
17
use SilverStripe\GraphQL\OperationResolver;
18
use SilverStripe\ORM\ValidationException;
19
use SilverStripe\ORM\ValidationResult;
20
use SilverStripe\Security\Authenticator;
21
use SilverStripe\Security\Member;
22
use SilverStripe\Security\Security;
23
24
class CreateTokenMutationCreator extends MutationCreator implements OperationResolver
25
{
26
    use RequiresAuthenticator;
27
    use MemberTokenGenerator;
28
    use Extensible;
29
30
    /**
31
     * Extra authenticators to use for logging in with username / password
32
     *
33
     * @var Authenticator[]
34
     */
35
    protected $customAuthenticators = [];
36
37
    /**
38
     * @return Authenticator[]
39
     */
40
    public function getCustomAuthenticators(): array
41
    {
42
        return $this->customAuthenticators;
43
    }
44
45
    /**
46
     * @param Authenticator[] $authenticators
47
     * @return CreateTokenMutationCreator
48
     */
49
    public function setCustomAuthenticators(array $authenticators): self
50
    {
51
        $this->customAuthenticators = $authenticators;
52
        return $this;
53
    }
54
55
    public function attributes(): array
56
    {
57
        return [
58
            'name'        => 'createToken',
59
            'description' => 'Creates a JWT token for a valid user'
60
        ];
61
    }
62
63
    public function type(): Type
64
    {
65
        return $this->manager->getType('MemberToken');
66
    }
67
68
    public function args(): array
69
    {
70
        return [
71
            'Email'    => ['type' => Type::nonNull(Type::string())],
72
            'Password' => ['type' => Type::string()]
73
        ];
74
    }
75
76
    /**
77
     * @param mixed $object
78
     * @param array $args
79
     * @param mixed $context
80
     * @param ResolveInfo $info
81
     * @return array
82
     * @throws NotFoundExceptionInterface
83
     * @throws ValidationException
84
     */
85
    public function resolve($object, array $args, $context, ResolveInfo $info): array
86
    {
87
        // Authenticate this member
88
        $request = Controller::curr()->getRequest();
89
        $member = $this->getAuthenticatedMember($args, $request);
90
91
        // Handle unauthenticated
92
        if (!$member) {
93
            return $this->generateResponse(TokenStatusEnum::STATUS_BAD_LOGIN);
94
        }
95
96
        // Create new token from this member
97
        $authenticator = $this->getJWTAuthenticator();
98
        $token = $authenticator->generateToken($request, $member);
99
        return $this->generateResponse(TokenStatusEnum::STATUS_OK, $member, $token->__toString());
100
    }
101
102
    /**
103
     * Get an authenticated member from the given request
104
     *
105
     * @param array $args
106
     * @param HTTPRequest $request
107
     * @return Member|MemberExtension
108
     */
109
    protected function getAuthenticatedMember(array $args, HTTPRequest $request): ?Member
110
    {
111
        // Login with authenticators
112
        foreach ($this->getLoginAuthenticators() as $authenticator) {
113
            $result = new ValidationResult();
114
            $member = $authenticator->authenticate($args, $request, $result);
115
            if ($member && $result->isValid()) {
116
                return $member;
117
            }
118
        }
119
120
        return null;
121
    }
122
123
    /**
124
     * Get any authenticator we should use for logging in users
125
     *
126
     * @return Authenticator[]|Generator
127
     */
128
    protected function getLoginAuthenticators(): Generator
129
    {
130
        // Check injected authenticators
131
        yield from $this->getCustomAuthenticators();
132
133
        // Get other login handlers from Security
134
        $security = Security::singleton();
135
        yield from $security->getApplicableAuthenticators(Authenticator::LOGIN);
136
    }
137
}
138