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