Passed
Push — master ( 79e4b8...16de75 )
by Andreas
18:13
created

midcom_connection::is_admin()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 6
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
c 0
b 0
f 0
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
    /**
21
     * Private cache for connection information
22
     *
23
     * @var array
24
     */
25
    private static $_data = [];
26
27
    /**
28
     * DB connection setup routine
29
     *
30
     * @param string $basedir The directory to look for config files if necessary
31
     * @throws Exception We use regular exceptions here, because this might run before things are properly set up
32
     * @return boolean Indicating success
33
     */
34
    public static function setup(string $basedir) : bool
35
    {
36
        if (file_exists($basedir . 'config/midgard-portable.inc.php')) {
37
            include $basedir . 'config/midgard-portable.inc.php';
38
            return midgard_connection::get_instance()->is_connected();
39
        }
40
        if (file_exists($basedir . 'config/midgard-portable-default.inc.php')) {
41
            include $basedir . 'config/midgard-portable-default.inc.php';
42
            //default config has in-memory db, so all the tables may be missing
43
            return midgard_storage::class_storage_exists('midgard_user');
44
        }
45
        throw new Exception("Could not connect to database, configuration file not found");
46
    }
47
48
    /**
49
     * Set Midgard log level
50
     *
51
     * @param string $loglevel Midgard log level
52
     */
53
    static function set_loglevel($loglevel) : bool
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
54
    {
55
        return midgard_connection::get_instance()->set_loglevel($loglevel);
56
    }
57
58
    /**
59
     * Set Midgard error code
60
     */
61 8
    public static function set_error(int $errorcode)
62
    {
63 8
        return midgard_connection::get_instance()->set_error($errorcode);
64
    }
65
66
    /**
67
     * Get Midgard error code
68
     */
69 35
    public static function get_error() : int
70
    {
71 35
        return midgard_connection::get_instance()->get_error();
72
    }
73
74
    /**
75
     * Get Midgard error message
76
     */
77 49
    public static function get_error_string() : string
78
    {
79 49
        return midgard_connection::get_instance()->get_error_string();
80
    }
81
82
    /**
83
     * Perform a login against the midgard backend
84
     */
85 59
    public static function login(string $username, string $password, bool $trusted = false) : ?midgard_user
86
    {
87
        $login_tokens = [
88 59
            'login' => $username,
89 59
            'authtype' => midcom::get()->config->get('auth_type'),
90
        ];
91
92
        try {
93 59
            $user = new midgard_user($login_tokens);
94
        } catch (mgd_exception $e) {
95
            return null;
96
        }
97 59
        if (!$trusted && !self::verify_password($password, $user->password)) {
98 1
            return null;
99
        }
100
101 59
        if (!$user->login()) {
102
            return null;
103
        }
104 59
        return $user;
105
    }
106
107 64
    public static function verify_password(string $password, string $hash) : bool
108
    {
109 64
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
110 64
            return password_verify($password, $hash);
111
        }
112
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
113
            $password = hash('sha256', $password);
114
        }
115
116
        return $password === $hash;
117
    }
118
119 82
    public static function prepare_password(string $password)
120
    {
121 82
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
122 82
            return password_hash($password, PASSWORD_DEFAULT);
123
        }
124
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
125
            return hash('sha256', $password);
126
        }
127
128
        return $password;
129
    }
130
131 1
    public static function is_user($person) : bool
132
    {
133 1
        if (empty($person->guid)) {
134
            return false;
135
        }
136 1
        $qb = new midgard_query_builder('midgard_user');
137 1
        $qb->add_constraint('person', '=', $person->guid);
138 1
        return $qb->count() > 0;
139
    }
140
141
    /**
142
     * Get current Midgard user ID
143
     */
144 65
    public static function get_user() : int
145
    {
146 65
        if ($user = midgard_connection::get_instance()->get_user()) {
147 39
            return $user->get_person()->id;
148
        }
149 26
        return 0;
150
    }
151
152
    /**
153
     * Check if the current user is admin
154
     */
155 8
    public static function is_admin() : bool
156
    {
157 8
        if ($user = midgard_connection::get_instance()->get_user()) {
158 8
            return $user->is_admin();
159
        }
160
        return false;
161
    }
162
163
    /**
164
     * Logout the current user, if any
165
     */
166 1
    public static function logout()
167
    {
168 1
        if ($user = midgard_connection::get_instance()->get_user()) {
169 1
            $user->logout();
170
        }
171 1
    }
172
173 412
    private static function _get(string $key)
174
    {
175 412
        if (isset(self::$_data[$key])) {
176 412
            return self::$_data[$key];
177
        }
178
179 1
        return null;
180
    }
181
182
    /**
183
     * Lists all available MgdSchema types
184
     */
185 6
    public static function get_schema_types() : array
186
    {
187 6
        if (!isset(self::$_data['schema_types'])) {
188
            $classnames = connection::get_em()->getConfiguration()->getMetadataDriverImpl()->getAllClassNames();
189
190
            self::$_data['schema_types'] = array_filter($classnames, function($input) {
191
                return is_subclass_of($input, mgdobject::class);
192
            });
193
        }
194 6
        return self::$_data['schema_types'];
195
    }
196
197
    /**
198
     * Get various pieces of information extracted from the URL
199
     *
200
     * @return mixed The data for the requested key or null if it doesn't exist
201
     */
202 412
    public static function get_url(string $key)
203
    {
204 412
        static $parsed = false;
205 412
        if (!$parsed) {
206
            $self = defined('OPENPSA2_PREFIX') ? OPENPSA2_PREFIX : '/';
207
208
            // we're only interested in the path, so use a dummy domain for simplicity's sake
209
            $url_components = parse_url("http://openpsa2.org{$_SERVER['REQUEST_URI']}");
210
            if ($self !== '/') {
211
                $url_components['path'] = preg_replace('|^' . $self . '|', '/', $url_components['path']);
212
            }
213
            self::_parse_url($url_components['path'], $self, substr($self, 0, -1));
214
            $parsed = true;
215
        }
216
217 412
        return self::_get($key);
218
    }
219
220
    /**
221
     * Enables themes to have subdirectories (which have a similar effect to mgd1 pages)
222
     *
223
     * @param string $uri The request path
224
     * @param string $self The instance's root URL
225
     * @param string $prefix The root URL's prefix, if any (corresponds to mgd1 host)
226
     */
227 1
    private static function _parse_url(string $uri, string $self, string $prefix)
228
    {
229 1
        $uri = preg_replace('/\/[\/]+/i', '/', $uri);
230 1
        $path_parts = explode('/', $uri);
231 1
        $page_style = '';
232 1
        $path = $self;
233
234 1
        self::$_data['argv'] = [];
235 1
        $args_started = false;
236 1
        foreach ($path_parts as $part) {
237 1
            if ($part === '') {
238 1
                continue;
239
            }
240 1
            if (    midcom::get()->config->get('theme')
241 1
                 && !$args_started
242 1
                 && self::check_page_exists($part)) {
243
                $page_style .= '/' . $part;
244
                $self .= $part . '/';
245
            } else {
246 1
                self::$_data['argv'][] = $part;
247 1
                $path .= $part . '/';
248 1
                $args_started = true;
249
            }
250
        }
251
252 1
        self::$_data['page_style'] = $page_style;
253 1
        self::$_data['uri'] = $path;
254 1
        self::$_data['self'] = $self;
255 1
        self::$_data['prefix'] = $prefix;
256 1
    }
257
258
259
    /**
260
     * Iterate through possible page directories in style-tree
261
     * and check if the page exists (as a folder).
262
     */
263 1
    private static function check_page_exists(string $page_name) : bool
264
    {
265 1
        $path_array = explode('/', midcom::get()->config->get('theme'));
0 ignored issues
show
Bug introduced by
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 ignore-type  annotation

265
        $path_array = explode('/', /** @scrutinizer ignore-type */ midcom::get()->config->get('theme'));
Loading history...
266
267 1
        while (!empty($path_array)) {
268 1
            $theme_path = implode('/', $path_array);
269 1
            if (is_dir(OPENPSA2_THEME_ROOT . $theme_path . '/style/' . $page_name)) {
270
                return true;
271
            }
272 1
            array_pop($path_array);
273
        }
274 1
        return false;
275
    }
276
277 1
    public static function get_unique_host_name() : string
278
    {
279 1
        if (null === self::_get('unique_host_name')) {
280 1
            self::$_data['unique_host_name'] = str_replace(':', '_', $_SERVER['SERVER_NAME']) . '_' . str_replace('/', '_', self::get_url('prefix'));
281
        }
282
283 1
        return self::$_data['unique_host_name'];
284
    }
285
}
286