flack /
openpsa
| 1 | <?php |
||||
| 2 | /** |
||||
| 3 | * @package midcom |
||||
| 4 | * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||||
| 5 | * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||||
| 6 | * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License |
||||
| 7 | */ |
||||
| 8 | |||||
| 9 | use midgard\portable\storage\connection; |
||||
| 10 | use midgard\portable\api\error\exception as mgd_exception; |
||||
| 11 | use midgard\portable\api\mgdobject; |
||||
| 12 | |||||
| 13 | /** |
||||
| 14 | * Wrapper for Midgard-related functionality |
||||
| 15 | * |
||||
| 16 | * @package midcom |
||||
| 17 | */ |
||||
| 18 | class midcom_connection |
||||
| 19 | { |
||||
| 20 | private static array $_data = []; |
||||
| 21 | |||||
| 22 | /** |
||||
| 23 | * DB connection setup routine |
||||
| 24 | * |
||||
| 25 | * @throws Exception We use regular exceptions here, because this might run before things are properly set up |
||||
| 26 | */ |
||||
| 27 | public static function setup(string $basedir) : bool |
||||
| 28 | { |
||||
| 29 | if (file_exists($basedir . 'config/midgard-portable.inc.php')) { |
||||
| 30 | include $basedir . 'config/midgard-portable.inc.php'; |
||||
| 31 | return midgard_connection::get_instance()->is_connected(); |
||||
| 32 | } |
||||
| 33 | if (file_exists($basedir . 'config/midgard-portable-default.inc.php')) { |
||||
| 34 | include $basedir . 'config/midgard-portable-default.inc.php'; |
||||
| 35 | //default config has in-memory db, so all the tables may be missing |
||||
| 36 | return midgard_storage::class_storage_exists('midgard_user'); |
||||
| 37 | } |
||||
| 38 | throw new Exception("Could not connect to database, configuration file not found"); |
||||
| 39 | } |
||||
| 40 | |||||
| 41 | /** |
||||
| 42 | * Set Midgard log level |
||||
| 43 | * |
||||
| 44 | * @param string $loglevel Midgard log level |
||||
| 45 | */ |
||||
| 46 | static function set_loglevel($loglevel) : bool |
||||
|
0 ignored issues
–
show
|
|||||
| 47 | { |
||||
| 48 | return midgard_connection::get_instance()->set_loglevel($loglevel); |
||||
| 49 | } |
||||
| 50 | |||||
| 51 | /** |
||||
| 52 | * Set Midgard error code |
||||
| 53 | */ |
||||
| 54 | 17 | public static function set_error(int $errorcode) |
|||
| 55 | { |
||||
| 56 | 17 | midgard_connection::get_instance()->set_error($errorcode); |
|||
| 57 | } |
||||
| 58 | |||||
| 59 | /** |
||||
| 60 | * Get Midgard error code |
||||
| 61 | */ |
||||
| 62 | 41 | public static function get_error() : int |
|||
| 63 | { |
||||
| 64 | 41 | return midgard_connection::get_instance()->get_error(); |
|||
| 65 | } |
||||
| 66 | |||||
| 67 | /** |
||||
| 68 | * Get Midgard error message |
||||
| 69 | */ |
||||
| 70 | 57 | public static function get_error_string() : string |
|||
| 71 | { |
||||
| 72 | 57 | return midgard_connection::get_instance()->get_error_string(); |
|||
| 73 | } |
||||
| 74 | |||||
| 75 | /** |
||||
| 76 | * Perform a login against the midgard backend |
||||
| 77 | */ |
||||
| 78 | 65 | public static function login(string $username, string $password, bool $trusted = false) : ?midgard_user |
|||
| 79 | { |
||||
| 80 | 65 | $login_tokens = [ |
|||
| 81 | 65 | 'login' => $username, |
|||
| 82 | 65 | 'authtype' => midcom::get()->config->get('auth_type'), |
|||
| 83 | 65 | ]; |
|||
| 84 | |||||
| 85 | try { |
||||
| 86 | 65 | $user = new midgard_user($login_tokens); |
|||
| 87 | } catch (mgd_exception) { |
||||
| 88 | return null; |
||||
| 89 | } |
||||
| 90 | 65 | if (!$trusted && !self::verify_password($password, $user->password)) { |
|||
| 91 | return null; |
||||
| 92 | } |
||||
| 93 | |||||
| 94 | 65 | $user->login(); |
|||
| 95 | 65 | return $user; |
|||
| 96 | } |
||||
| 97 | |||||
| 98 | 72 | public static function verify_password(string $password, string $hash) : bool |
|||
| 99 | { |
||||
| 100 | 72 | if (midcom::get()->config->get('auth_type') == 'Legacy') { |
|||
| 101 | 72 | return password_verify($password, $hash); |
|||
| 102 | } |
||||
| 103 | if (midcom::get()->config->get('auth_type') == 'SHA256') { |
||||
| 104 | $password = hash('sha256', $password); |
||||
| 105 | } |
||||
| 106 | |||||
| 107 | return $password === $hash; |
||||
| 108 | } |
||||
| 109 | |||||
| 110 | 90 | public static function prepare_password(string $password) : string |
|||
| 111 | { |
||||
| 112 | 90 | if (midcom::get()->config->get('auth_type') == 'Legacy') { |
|||
| 113 | 90 | return password_hash($password, PASSWORD_DEFAULT); |
|||
| 114 | } |
||||
| 115 | if (midcom::get()->config->get('auth_type') == 'SHA256') { |
||||
| 116 | return hash('sha256', $password); |
||||
| 117 | } |
||||
| 118 | |||||
| 119 | return $password; |
||||
| 120 | } |
||||
| 121 | |||||
| 122 | /** |
||||
| 123 | * Get current Midgard user ID |
||||
| 124 | */ |
||||
| 125 | 62 | public static function get_user() : int |
|||
| 126 | { |
||||
| 127 | 62 | if ($user = midgard_connection::get_instance()->get_user()) { |
|||
| 128 | 34 | return $user->get_person()->id; |
|||
| 129 | } |
||||
| 130 | 28 | return 0; |
|||
| 131 | } |
||||
| 132 | |||||
| 133 | /** |
||||
| 134 | * Logout the current user, if any |
||||
| 135 | */ |
||||
| 136 | 1 | public static function logout() |
|||
| 137 | { |
||||
| 138 | 1 | if ($user = midgard_connection::get_instance()->get_user()) { |
|||
| 139 | 1 | $user->logout(); |
|||
| 140 | } |
||||
| 141 | } |
||||
| 142 | |||||
| 143 | 367 | private static function _get(string $key) |
|||
| 144 | { |
||||
| 145 | 367 | return self::$_data[$key] ?? null; |
|||
| 146 | } |
||||
| 147 | |||||
| 148 | /** |
||||
| 149 | * Lists all available MgdSchema types |
||||
| 150 | */ |
||||
| 151 | 6 | public static function get_schema_types() : array |
|||
| 152 | { |
||||
| 153 | 6 | if (!isset(self::$_data['schema_types'])) { |
|||
| 154 | $classnames = connection::get_em()->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); |
||||
| 155 | |||||
| 156 | self::$_data['schema_types'] = array_filter($classnames, function(string $input) { |
||||
| 157 | return is_subclass_of($input, mgdobject::class); |
||||
| 158 | }); |
||||
| 159 | } |
||||
| 160 | 6 | return self::$_data['schema_types']; |
|||
| 161 | } |
||||
| 162 | |||||
| 163 | /** |
||||
| 164 | * Get various pieces of information extracted from the URL |
||||
| 165 | * |
||||
| 166 | * @return mixed The data for the requested key or null if it doesn't exist |
||||
| 167 | */ |
||||
| 168 | 367 | public static function get_url(string $key) |
|||
| 169 | { |
||||
| 170 | 367 | static $parsed = false; |
|||
| 171 | 367 | if (!$parsed) { |
|||
| 172 | $self = defined('OPENPSA2_PREFIX') ? OPENPSA2_PREFIX : '/'; |
||||
| 173 | |||||
| 174 | // we're only interested in the path, so use a dummy domain for simplicity's sake |
||||
| 175 | $url_path = (string) parse_url("https://openpsa2.org{$_SERVER['REQUEST_URI']}", PHP_URL_PATH); |
||||
| 176 | if ($self !== '/') { |
||||
| 177 | $url_path = preg_replace('|^' . $self . '|', '/', $url_path); |
||||
| 178 | } |
||||
| 179 | self::_parse_url($url_path, $self, substr($self, 0, -1)); |
||||
| 180 | $parsed = true; |
||||
| 181 | } |
||||
| 182 | |||||
| 183 | 367 | return self::_get($key); |
|||
| 184 | } |
||||
| 185 | |||||
| 186 | /** |
||||
| 187 | * Enables themes to have subdirectories (which have a similar effect to mgd1 pages) |
||||
| 188 | * |
||||
| 189 | * @param string $uri The request path |
||||
| 190 | * @param string $self The instance's root URL |
||||
| 191 | * @param string $prefix The root URL's prefix, if any (corresponds to mgd1 host) |
||||
| 192 | */ |
||||
| 193 | private static function _parse_url(string $uri, string $self, string $prefix) |
||||
| 194 | { |
||||
| 195 | $path_parts = explode('/', $uri); |
||||
| 196 | $page_style = ''; |
||||
| 197 | $path = $uri; |
||||
| 198 | |||||
| 199 | $args_started = false; |
||||
| 200 | foreach ($path_parts as $part) { |
||||
| 201 | if ($part === '') { |
||||
| 202 | continue; |
||||
| 203 | } |
||||
| 204 | if ( midcom::get()->config->get('theme') |
||||
| 205 | && !$args_started |
||||
| 206 | && self::check_page_exists($part)) { |
||||
| 207 | $page_style .= '/' . $part; |
||||
| 208 | $self .= $part . '/'; |
||||
| 209 | $path = substr($path, strlen($part) + 1); |
||||
| 210 | } else { |
||||
| 211 | $args_started = true; |
||||
| 212 | } |
||||
| 213 | } |
||||
| 214 | |||||
| 215 | self::$_data['page_style'] = $page_style; |
||||
| 216 | self::$_data['uri'] = $path; |
||||
| 217 | self::$_data['self'] = $self; |
||||
| 218 | self::$_data['prefix'] = $prefix; |
||||
| 219 | } |
||||
| 220 | |||||
| 221 | /** |
||||
| 222 | * Iterate through possible page directories in style-tree |
||||
| 223 | * and check if the page exists (as a folder). |
||||
| 224 | */ |
||||
| 225 | private static function check_page_exists(string $page_name) : bool |
||||
| 226 | { |
||||
| 227 | $prefix = midcom::get()->getProjectDir() . '/var/themes/'; |
||||
| 228 | $path_array = explode('/', midcom::get()->config->get('theme')); |
||||
|
0 ignored issues
–
show
It seems like
midcom::get()->config->get('theme') can also be of type null; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 229 | while (!empty($path_array)) { |
||||
| 230 | $theme_path = implode('/', $path_array); |
||||
| 231 | if (is_dir($prefix . $theme_path . '/style/' . $page_name)) { |
||||
| 232 | return true; |
||||
| 233 | } |
||||
| 234 | array_pop($path_array); |
||||
| 235 | } |
||||
| 236 | return false; |
||||
| 237 | } |
||||
| 238 | } |
||||
| 239 |
Adding explicit visibility (
private,protected, orpublic) is generally recommend to communicate to other developers how, and from where this method is intended to be used.