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