xref: /plugin/twofactor/Manager.php (revision 8b7620a8e0c445f8fa437fe73abebe02c1bc0940)
1<?php
2
3namespace dokuwiki\plugin\twofactor;
4
5/**
6 * Manages the child plugins etc.
7 */
8class Manager
9{
10    /** @var Manager */
11    protected static $instance;
12
13    /** @var bool */
14    protected $ready = false;
15
16    /** @var string[] */
17    protected $classes = [];
18
19    /** @var Provider[] */
20    protected $providers;
21
22    /**
23     * Constructor
24     */
25    protected function __construct()
26    {
27        $this->classes = $this->getProviderClasses();
28
29        $attribute = plugin_load('helper', 'attribute');
30        if ($attribute === null) {
31            msg('The attribute plugin is not available, 2fa disabled', -1);
32        }
33
34        if (!count($this->classes)) {
35            msg('No suitable 2fa providers found, 2fa disabled', -1);
36            return;
37        }
38
39        $this->ready = true;
40    }
41
42    /**
43     * Get the instance of this singleton
44     *
45     * @return Manager
46     */
47    public static function getInstance()
48    {
49        if (self::$instance === null) {
50            self::$instance = new Manager();
51        }
52        return self::$instance;
53    }
54
55    /**
56     * Is the plugin ready to be used?
57     *
58     * @return bool
59     */
60    public function isReady()
61    {
62        return $this->ready;
63    }
64
65    /**
66     * Get all available providers
67     *
68     * @return Provider[]
69     */
70    public function getAllProviders()
71    {
72        global $INPUT;
73        $user = $INPUT->server->str('REMOTE_USER');
74        if (!$user) {
75            throw new \RuntimeException('2fa Providers instantiated before user available');
76        }
77
78        if ($this->providers === null) {
79            $this->providers = [];
80            foreach ($this->classes as $class) {
81                $this->providers[] = new $class($user);
82            }
83        }
84
85        return $this->providers;
86    }
87
88    /**
89     * Find all available provider classes
90     *
91     * @return string[];
92     */
93    protected function getProviderClasses()
94    {
95        // FIXME this relies on naming alone, we might want to use an action for registering
96        $plugins = plugin_list('helper');
97        $plugins = array_filter($plugins, function ($plugin) {
98            return $plugin !== 'twofactor' && substr($plugin, 0, 9) === 'twofactor';
99        });
100
101        $classes = [];
102        foreach ($plugins as $plugin) {
103            $class = 'helper_plugin_' . $plugin;
104            if (is_a($class, Provider::class, true)) {
105                $classes[] = $class;
106            }
107        }
108
109        return $classes;
110    }
111
112}
113