Passed
Push — master ( 339ea2...7794c5 )
by Hesham
04:22
created

LumenerController::_runAdminer()   C

Complexity

Conditions 12
Paths 8

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 30
rs 6.9666
c 0
b 0
f 0
cc 12
nc 8
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Lumener\Controllers;
3
4
use Illuminate\Routing\Controller;
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Artisan;
7
8
class LumenerController extends Controller
9
{
10
    protected $adminer;
11
    protected $adminer_object;
12
    protected $plugins_path;
13
    protected $allowed_dbs;
14
    protected $protected_dbs;
15
    protected $request;
16
17
    public function __construct(Request $request)
18
    {
19
        if (method_exists(\Route::class, 'hasMiddlewareGroup')
20
        && \Route::hasMiddlewareGroup('lumener')) {
21
            $this->middleware('lumener');
22
        }
23
        // LumenerServiceProvider::register holds the middleware register
24
        // so it does not need to be addeed manually.
25
        // User-defined middleware is handled during route definition for Lumen
26
        $this->adminer = LUMENER_STORAGE.'/adminer.php';
27
        $this->adminer_object = __DIR__.'/../logic/adminer_object.php';
28
        $this->plugins_path = LUMENER_STORAGE.'/plugins';
29
        $this->request = $request;
30
    }
31
32
    public function __call($method, $params)
33
    {
34
        if (strncasecmp($method, "get", 3) === 0) {
35
            $var = preg_replace_callback('/[A-Z]/', function ($c) {
36
                return '_'.strtolower($c[0]);
37
            }, lcfirst(substr($method, 3)));
38
            return $this->$var;
39
        }
40
    }
41
42
    public function index()
43
    {
44
        if ($this->request->cookie('adminer_logged_out')
45
            && config('lumener.logout_redirect')) {
46
            return redirect(config('lumener.logout_redirect'));
47
        }
48
        if (isset($_POST['logout'])) {
49
            $t = encrypt(time());
50
            $h = "Set-Cookie: adminer_logged_out={$t}; expires=".gmdate(
51
                "D, d M Y H:i:s",
52
                time() + config('lumener.logout_cooldown', 10)
53
            )." GMT; path=".preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]);
54
            header($h);
55
        }
56
        if (file_exists($this->adminer)) {
57
            return $this->_runAdminer();
58
        } else {
59
            return '<div style="text-align:center;color: red;
60
                                margin-top: 200px;font-weight:bold;">
61
                      Adminer was NOT found.
62
                      Run <span style="color:lightgreen;background:black;
63
                                       padding: 5px;border: 5px dashed white;">
64
                                       php artisan lumener:update --force</span>
65
                                       to fix any issues.
66
                    </div>
67
            ';
68
        }
69
    }
70
71
    public function update()
72
    {
73
        Artisan::call('lumener:update');
74
        return nl2br(Artisan::output());
75
    }
76
77
    public function getResource()
78
    {
79
        $file = $this->request->get('file');
80
        $path = realpath(LUMENER_STORAGE."/{$file}");
81
        // Prevent risky file fetching
82
        // This check is very important, it's a major security risk to allow
83
        // Fetching files outside the LUMENER_STORAGE directory
84
        if (
85
            $path === false
86
            || strncmp($path, LUMENER_STORAGE, strlen(LUMENER_STORAGE)) !== 0
87
        ) {
88
            abort(403);
89
        }
90
        $type = $this->request->get('type', mime_content_type($path));
91
        return response()->download($path, $file, ["Content-Type"=>$type]);
92
    }
93
94
    public function isDBBlocked($db)
95
    {
96
        return
97
        (
98
            $this->allowed_dbs !== null
99
            && !in_array($db, $this->allowed_dbs)
100
        )
101
        ||
102
        (
103
            $this->protected_dbs !== null
104
            && in_array($db, $this->protected_dbs)
105
        );
106
    }
107
108
    private function _runAdminer()
109
    {
110
        if (!isset($_GET['username']) && !isset($_POST['auth'])
111
            && config('lumener.auto_login')
112
            && !$this->request->cookie('adminer_logged_out')) {
113
            // Skip login screen
114
            $_GET['username'] =
115
                config('lumener.db.username', env("DB_USERNAME"));
116
            $_GET['db'] =
117
                config('lumener.db.database', env("DB_DATABASE"));
118
            // Password is set in the adminer extension
119
        }
120
        // Security Check
121
        $this->allowed_dbs = config('lumener.security.allowed_db');
122
        $this->protected_dbs = config('lumener.security.protected_db');
123
124
        if ((isset($_GET['db']) && $_GET['db']
125
            && $this->isDBBlocked($_GET['db']))
126
        || (isset($_POST['auth']['db']) && $_POST['auth']['db']
127
            && $this->isDBBlocked($_POST['auth']['db']))) {
128
            abort(403);
129
        }
130
131
        $content =
132
            $this->_runGetBuffer([$this->adminer_object, $this->adminer]);
133
134
        if (strpos($content, "<!DOCTYPE html>") === false) {
135
            die($content);
136
        }
137
        return $content;
138
    }
139
140
    private function _runGetBuffer($files, $allowed_errors=[E_WARNING])
141
    {
142
        // Require files
143
        ob_implicit_flush(0);
144
        ob_start();
145
        try {
146
            foreach ($files as $file) {
147
                // require because include will not throw the adminer_exit error
148
                require($file);
149
            }
150
        } catch (\ErrorException $e) {
151
            if (config('lumener.debug')
152
            || !in_array($e->getSeverity(), $allowed_errors)) {
153
                throw $e;
154
            }
155
        }
156
        $content = "";
157
        while ($level = ob_get_clean()) {
158
            $content = $level . $content;
159
        }
160
        return $content;
161
    }
162
}
163