Completed
Push — master ( 021232...087dfb )
by Michael
02:43
created

gtickets.php ➔ admin_refcheck()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
cc 4
eloc 11
c 4
b 0
f 1
nc 5
nop 1
dl 0
loc 17
rs 9.2
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 9 and the first side effect is on line 259.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
// GIJOE's Ticket Class (based on Marijuana's Oreteki XOOPS)
3
// nobunobu's suggestions are applied
4
5
if (!class_exists('XoopsGTicket')) {
6
    /**
7
     * Class XoopsGTicket
8
     */
9
    class XoopsGTicket
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
10
    {
11
        public $_errors       = array();
12
        public $_latest_token = '';
13
14
        // render form as plain html
15
        /**
16
         * @param  string $salt
17
         * @param  int    $timeout
18
         * @param  string $area
19
         * @return string
20
         */
21
        public function getTicketHtml($salt = '', $timeout = 1800, $area = '')
22
        {
23
            return '<input type="hidden" name="XOOPS_G_TICKET" value="' . $this->issue($salt, $timeout, $area) . '" />';
24
        }
25
26
        // returns an object of XoopsFormHidden including theh ticket
27
        /**
28
         * @param  string $salt
29
         * @param  int    $timeout
30
         * @param  string $area
31
         * @return XoopsFormHidden
32
         */
33
        public function getTicketXoopsForm($salt = '', $timeout = 1800, $area = '')
34
        {
35
            return new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area));
36
        }
37
38
        // add a ticket as Hidden Element into XoopsForm
39
        /**
40
         * @param        $form
41
         * @param string $salt
42
         * @param int    $timeout
43
         * @param string $area
44
         */
45
        public function addTicketXoopsFormElement(&$form, $salt = '', $timeout = 1800, $area = '')
46
        {
47
            $form->addElement(new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area)));
48
        }
49
50
        // returns an array for xoops_confirm() ;
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
51
        /**
52
         * @param  string $salt
53
         * @param  int    $timeout
54
         * @param  string $area
55
         * @return array
56
         */
57
        public function getTicketArray($salt = '', $timeout = 1800, $area = '')
58
        {
59
            return array('XOOPS_G_TICKET' => $this->issue($salt, $timeout, $area));
60
        }
61
62
        // return GET parameter string.
63
        /**
64
         * @param  string $salt
65
         * @param  bool   $noamp
66
         * @param  int    $timeout
67
         * @param  string $area
68
         * @return string
69
         */
70
        public function getTicketParamString($salt = '', $noamp = false, $timeout = 1800, $area = '')
71
        {
72
            return ($noamp ? '' : '&amp;') . 'XOOPS_G_TICKET=' . $this->issue($salt, $timeout, $area);
73
        }
74
75
        // issue a ticket
76
        /**
77
         * @param  string $salt
78
         * @param  int    $timeout
79
         * @param  string $area
80
         * @return string
81
         */
82
        public function issue($salt = '', $timeout = 1800, $area = '')
0 ignored issues
show
Coding Style introduced by
issue uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
issue uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
83
        {
84
            global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
85
86
            if ('' === $salt) {
87
                $salt= '$2y$07$' . str_replace('+', '.', base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)));
88
            }
89
            // create a token
90
            list($usec, $sec) = explode(' ', microtime());
91
            $appendix_salt       = empty($_SERVER['PATH']) ? XOOPS_DB_NAME : $_SERVER['PATH'];
92
            $token               = crypt($salt . $usec . $appendix_salt . $sec, $salt);
93
            $this->_latest_token = $token;
94
95
            if (empty($_SESSION['XOOPS_G_STUBS'])) {
96
                $_SESSION['XOOPS_G_STUBS'] = array();
97
            }
98
99
            // limit max stubs 10
100
            if (count($_SESSION['XOOPS_G_STUBS']) > 10) {
101
                $_SESSION['XOOPS_G_STUBS'] = array_slice($_SESSION['XOOPS_G_STUBS'], -10);
102
            }
103
104
            // record referer if browser send it
105
            $referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['REQUEST_URI'];
106
107
            // area as module's dirname
108
            if (!$area && is_object(@$xoopsModule)) {
109
                $area = $xoopsModule->getVar('dirname');
110
            }
111
112
            // store stub
113
            $_SESSION['XOOPS_G_STUBS'][] = array(
114
                'expire'  => time() + $timeout,
115
                'referer' => $referer,
116
                'area'    => $area,
117
                'token'   => $token
118
            );
119
120
            // paid md5ed token as a ticket
121
            return md5($token . XOOPS_DB_PREFIX);
122
        }
123
124
        // check a ticket
125
        /**
126
         * @param  bool   $post
127
         * @param  string $area
128
         * @return bool
129
         */
130
        public function check($post = true, $area = '')
0 ignored issues
show
Coding Style introduced by
check uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
check uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
check uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
check uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
131
        {
132
            global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
133
134
            $this->_errors = array();
135
136
            // CHECK: stubs are not stored in session
137
            if (empty($_SESSION['XOOPS_G_STUBS']) || !is_array($_SESSION['XOOPS_G_STUBS'])) {
138
                $this->clear();
139
                $this->_errors[] = 'Invalid Session';
140
141
                return false;
142
            }
143
144
            // get key&val of the ticket from a user's query
145
            if ($post) {
146
                $ticket = empty($_POST['XOOPS_G_TICKET']) ? '' : $_POST['XOOPS_G_TICKET'];
147
            } else {
148
                $ticket = empty($_GET['XOOPS_G_TICKET']) ? '' : $_GET['XOOPS_G_TICKET'];
149
            }
150
151
            // CHECK: no tickets found
152
            if (empty($ticket)) {
153
                $this->clear();
154
                $this->_errors[] = 'Irregular post found';
155
156
                return false;
157
            }
158
159
            // gargage collection & find a right stub
160
            $stubs_tmp                 = $_SESSION['XOOPS_G_STUBS'];
161
            $_SESSION['XOOPS_G_STUBS'] = array();
162
            foreach ($stubs_tmp as $stub) {
163
                // default lifetime 30min
164
                if ($stub['expire'] >= time()) {
165
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
166
                        $found_stub = $stub;
167
                    } else {
168
                        // store the other valid stubs into session
169
                        $_SESSION['XOOPS_G_STUBS'][] = $stub;
170
                    }
171
                } else {
172
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
173
                        // not CSRF but Time-Out
174
                        $timeout_flag = true;
175
                    }
176
                }
177
            }
178
179
            // CHECK: the right stub found or not
180
            if (empty($found_stub)) {
181
                $this->clear();
182
                if (empty($timeout_flag)) {
183
                    $this->_errors[] = 'Invalid Session';
184
                } else {
185
                    $this->_errors[] = 'Time out';
186
                }
187
188
                return false;
189
            }
190
191
            // set area if necessary
192
            // area as module's dirname
193
            if (!$area && is_object(@$xoopsModule)) {
194
                $area = $xoopsModule->getVar('dirname');
195
            }
196
197
            // check area or referer
198
            if (@$found_stub['area'] == $area) {
199
                $area_check = true;
200
            }
201
            if (!empty($found_stub['referer']) && true === strpos(@$_SERVER['HTTP_REFERER'], $found_stub['referer'])) {
202
                $referer_check = true;
203
            }
204
205
            // if ( empty( $area_check ) || empty( $referer_check ) ) { // restrict
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
206
            if (empty($area_check) && empty($referer_check)) { // loose
207
                $this->clear();
208
                $this->_errors[] = 'Invalid area or referer';
209
210
                return false;
211
            }
212
213
            // all green
214
            return true;
215
        }
216
217
        // clear all stubs
218
        public function clear()
0 ignored issues
show
Coding Style introduced by
clear uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
219
        {
220
            $_SESSION['XOOPS_G_STUBS'] = array();
221
        }
222
223
        // Ticket Using
224
        /**
225
         * @return bool
226
         */
227
        public function using()
0 ignored issues
show
Coding Style introduced by
using uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
228
        {
229
            if (!empty($_SESSION['XOOPS_G_STUBS'])) {
230
                return true;
231
            } else {
232
                return false;
233
            }
234
        }
235
236
        // return errors
237
        /**
238
         * @param  bool $ashtml
239
         * @return array|string
240
         */
241
        public function getErrors($ashtml = true)
242
        {
243
            if ($ashtml) {
244
                $ret = '';
245
                foreach ($this->_errors as $msg) {
246
                    $ret .= "$msg<br>\n";
247
                }
248
            } else {
249
                $ret = $this->_errors;
250
            }
251
252
            return $ret;
253
        }
254
255
        // end of class
256
    }
257
258
    // create a instance in global scope
259
    $GLOBALS['xoopsGTicket'] = new XoopsGTicket();
260
}
261
262
if (!function_exists('admin_refcheck')) {
263
264
    //Admin Referer Check By Marijuana(Rev.011)
265
    /**
266
     * @param  string $chkref
267
     * @return bool
268
     */
269
    function admin_refcheck($chkref = '')
0 ignored issues
show
Coding Style introduced by
admin_refcheck uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
270
    {
271
        if (empty($_SERVER['HTTP_REFERER'])) {
272
            return true;
273
        } else {
274
            $ref = $_SERVER['HTTP_REFERER'];
275
        }
276
        $cr = XOOPS_URL;
277
        if ($chkref != '') {
278
            $cr .= $chkref;
279
        }
280
        if (strpos($ref, $cr) !== 0) {
281
            return false;
282
        }
283
284
        return true;
285
    }
286
}
287