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