Completed
Push — master ( 4e92df...3d6026 )
by Robbie
12s
created

MethodRegistry::getBackupMethod()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php declare(strict_types=1);
2
3
namespace SilverStripe\MFA\Service;
4
5
use SilverStripe\Core\Config\Configurable;
6
use SilverStripe\Core\Injector\Injectable;
7
use SilverStripe\Core\Injector\Injector;
8
use SilverStripe\MFA\BackupCode\Method;
9
use SilverStripe\MFA\Method\MethodInterface;
10
use UnexpectedValueException;
11
12
/**
13
 * A service class that holds the configuration for enabled MFA methods and facilitates providing these methods
14
 */
15
class MethodRegistry
16
{
17
    use Configurable;
18
    use Injectable;
19
20
    /**
21
     * List of configured MFA methods. These should be class names that implement MethodInterface
22
     *
23
     * @config
24
     * @var string[]
25
     */
26
    private static $methods = [];
0 ignored issues
show
introduced by
The private property $methods is not used, and could be removed.
Loading history...
27
28
    /**
29
     * A string referring to the classname of the method (implementing SilverStripe\MFA\Method\MethodInterface) that is
30
     * to be used as the back-up method for MFA. This alters the registration of this method to be required - a forced
31
     * registration once the user has registered at least one other method. Additionally it cannot be set as the default
32
     * method for a user to log in with.
33
     *
34
     * @config
35
     * @var string
36
     */
37
    private static $default_backup_method = Method::class;
0 ignored issues
show
introduced by
The private property $default_backup_method is not used, and could be removed.
Loading history...
38
39
    /**
40
     * Request cache of instantiated method instances
41
     *
42
     * @var MethodInterface[]
43
     */
44
    protected $methodInstances;
45
46
    /**
47
     * Get implementations of all configured methods
48
     *
49
     * @return MethodInterface[]
50
     * @throws UnexpectedValueException When an invalid method is registered
51
     */
52
    public function getMethods(): array
53
    {
54
        if (is_array($this->methodInstances)) {
0 ignored issues
show
introduced by
The condition is_array($this->methodInstances) is always true.
Loading history...
55
            return $this->methodInstances;
56
        }
57
58
        $configuredMethods = (array) $this->config()->get('methods');
59
60
        $allMethods = [];
61
62
        foreach ($configuredMethods as $method) {
63
            $method = Injector::inst()->get($method);
64
65
            if (!$method instanceof MethodInterface) {
66
                throw new UnexpectedValueException(sprintf(
67
                    'Given method "%s" does not implement %s',
68
                    $method,
69
                    MethodInterface::class
70
                ));
71
            }
72
73
            $allMethods[] = $method;
74
        }
75
76
        return $this->methodInstances = $allMethods;
77
    }
78
79
    /**
80
     * Helper method to indicate whether any MFA methods are registered
81
     *
82
     * @return bool
83
     */
84
    public function hasMethods(): bool
85
    {
86
        return count($this->getMethods()) > 0;
87
    }
88
89
    /**
90
     * Indicates whether the given method is registered as the back-up method for MFA
91
     *
92
     * @param MethodInterface $method
93
     * @return bool
94
     */
95
    public function isBackupMethod(MethodInterface $method): bool
96
    {
97
        $configuredBackupMethod = $this->config()->get('default_backup_method');
98
        return is_string($configuredBackupMethod) && is_a($method, $configuredBackupMethod);
99
    }
100
101
    /**
102
     * Get the configured backup method
103
     *
104
     * @return MethodInterface|null
105
     */
106
    public function getBackupMethod(): ?MethodInterface
107
    {
108
        foreach ($this->getMethods() as $method) {
109
            if ($this->isBackupMethod($method)) {
110
                return $method;
111
            }
112
        }
113
114
        return null;
115
    }
116
117
    /**
118
     * Fetches a Method by its URL Segment
119
     *
120
     * @param string $segment
121
     * @return MethodInterface|null
122
     */
123
    public function getMethodByURLSegment(string $segment): ?MethodInterface
124
    {
125
        foreach ($this->getMethods() as $method) {
126
            if ($method->getURLSegment() === $segment) {
127
                return $method;
128
            }
129
        }
130
131
        return null;
132
    }
133
}
134