Passed
Push — newinternal-releasecandidate ( 40acd0...67549a )
by Simon
10:15
created
includes/Pages/UserAuth/PageLogout.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -14,22 +14,22 @@
 block discarded – undo
14 14
 
15 15
 class PageLogout extends InternalPageBase
16 16
 {
17
-    /**
18
-     * Main function for this page, when no specific actions are called.
19
-     */
20
-    protected function main()
21
-    {
22
-        if(WebRequest::wasPosted()) {
23
-            Session::destroy();
24
-            $this->redirect("login");
25
-            return;
26
-        }
17
+	/**
18
+	 * Main function for this page, when no specific actions are called.
19
+	 */
20
+	protected function main()
21
+	{
22
+		if(WebRequest::wasPosted()) {
23
+			Session::destroy();
24
+			$this->redirect("login");
25
+			return;
26
+		}
27 27
 
28
-        $this->redirect();
29
-    }
28
+		$this->redirect();
29
+	}
30 30
 
31
-    protected function isProtectedPage()
32
-    {
33
-        return false;
34
-    }
31
+	protected function isProtectedPage()
32
+	{
33
+		return false;
34
+	}
35 35
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@
 block discarded – undo
19 19
      */
20 20
     protected function main()
21 21
     {
22
-        if(WebRequest::wasPosted()) {
22
+        if (WebRequest::wasPosted()) {
23 23
             Session::destroy();
24 24
             $this->redirect("login");
25 25
             return;
Please login to merge, or discard this patch.
includes/WebStart.php 1 patch
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -32,225 +32,225 @@
 block discarded – undo
32 32
  */
33 33
 class WebStart extends ApplicationBase
34 34
 {
35
-    /**
36
-     * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
37
-     *                                    routers and hence different URL mappings
38
-     */
39
-    private $requestRouter;
40
-    /**
41
-     * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
42
-     */
43
-    private $isPublic = false;
44
-
45
-    /**
46
-     * WebStart constructor.
47
-     *
48
-     * @param SiteConfiguration $configuration The site configuration
49
-     * @param IRequestRouter    $router        The request router to use
50
-     */
51
-    public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
52
-    {
53
-        parent::__construct($configuration);
54
-
55
-        $this->requestRouter = $router;
56
-    }
57
-
58
-    /**
59
-     * @param ITask             $page
60
-     * @param SiteConfiguration $siteConfiguration
61
-     * @param PdoDatabase       $database
62
-     * @param PdoDatabase       $notificationsDatabase
63
-     *
64
-     * @return void
65
-     */
66
-    protected function setupHelpers(
67
-        ITask $page,
68
-        SiteConfiguration $siteConfiguration,
69
-        PdoDatabase $database,
70
-        PdoDatabase $notificationsDatabase = null
71
-    ) {
72
-        parent::setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
73
-
74
-        if ($page instanceof PageBase) {
75
-            $page->setTokenManager(new TokenManager());
76
-            $page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
77
-
78
-            if ($page instanceof InternalPageBase) {
79
-                $page->setTypeAheadHelper(new TypeAheadHelper());
80
-
81
-                $identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration,
82
-                    $database);
83
-                $page->setIdentificationVerifier($identificationVerifier);
84
-
85
-                $page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));
86
-
87
-                if ($siteConfiguration->getTitleBlacklistEnabled()) {
88
-                    $page->setBlacklistHelper(new FakeBlacklistHelper());
89
-                }
90
-                else {
91
-                    $page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(),
92
-                        $siteConfiguration->getMediawikiWebServiceEndpoint()));
93
-                }
94
-            }
95
-        }
96
-    }
97
-
98
-    /**
99
-     * Application entry point.
100
-     *
101
-     * Sets up the environment and runs the application, performing any global cleanup operations when done.
102
-     */
103
-    public function run()
104
-    {
105
-        try {
106
-            if ($this->setupEnvironment()) {
107
-                $this->main();
108
-            }
109
-        }
110
-        catch (EnvironmentException $ex) {
111
-            ob_end_clean();
112
-            print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
113
-        }
114
-        catch (ReadableException $ex) {
115
-            ob_end_clean();
116
-            print $ex->getReadableError();
117
-        }
118
-        finally {
119
-            $this->cleanupEnvironment();
120
-        }
121
-    }
122
-
123
-    /**
124
-     * Environment setup
125
-     *
126
-     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
127
-     * and shut down prematurely.
128
-     *
129
-     * @return bool
130
-     * @throws EnvironmentException
131
-     */
132
-    protected function setupEnvironment()
133
-    {
134
-        // initialise global exception handler
135
-        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
136
-        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
137
-
138
-        // start output buffering if necessary
139
-        if (ob_get_level() === 0) {
140
-            ob_start();
141
-        }
142
-
143
-        // initialise super-global providers
144
-        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
145
-
146
-        if (Offline::isOffline()) {
147
-            print Offline::getOfflineMessage($this->isPublic());
148
-            ob_end_flush();
149
-
150
-            return false;
151
-        }
152
-
153
-        // Call parent setup
154
-        if (!parent::setupEnvironment()) {
155
-            return false;
156
-        }
157
-
158
-        // Start up sessions
159
-        Session::start();
160
-
161
-        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
162
-        // get the current user cached.
163
-        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
164
-        // session I suppose.
165
-        $this->checkForceLogout();
166
-
167
-        // environment initialised!
168
-        return true;
169
-    }
170
-
171
-    /**
172
-     * Main application logic
173
-     */
174
-    protected function main()
175
-    {
176
-        // Get the right route for the request
177
-        $page = $this->requestRouter->route();
178
-
179
-        $siteConfiguration = $this->getConfiguration();
180
-        $database = PdoDatabase::getDatabaseConnection('acc');
181
-
182
-        if ($siteConfiguration->getIrcNotificationsEnabled()) {
183
-            $notificationsDatabase = PdoDatabase::getDatabaseConnection('notifications');
184
-        }
185
-        else {
186
-            // @todo federated table here?
187
-            $notificationsDatabase = $database;
188
-        }
189
-
190
-        $this->setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
191
-
192
-        /* @todo Remove this global statement! It's here for User.php, which does far more than it should. */
193
-        global $oauthProtocolHelper;
194
-        $oauthProtocolHelper = $page->getOAuthProtocolHelper();
195
-
196
-        /* @todo Remove this global statement! It's here for Request.php, which does far more than it should. */
197
-        global $globalXffTrustProvider;
198
-        $globalXffTrustProvider = $page->getXffTrustProvider();
199
-
200
-        // run the route code for the request.
201
-        $page->execute();
202
-    }
203
-
204
-    /**
205
-     * Any cleanup tasks should go here
206
-     *
207
-     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
208
-     * This should *only* be for cleaning up, no logic should go here.
209
-     */
210
-    protected function cleanupEnvironment()
211
-    {
212
-        // Clean up anything we splurged after sending the page.
213
-        if (ob_get_level() > 0) {
214
-            for ($i = ob_get_level(); $i > 0; $i--) {
215
-                ob_end_clean();
216
-            }
217
-        }
218
-    }
219
-
220
-    private function checkForceLogout()
221
-    {
222
-        $database = PdoDatabase::getDatabaseConnection('acc');
223
-
224
-        $sessionUserId = WebRequest::getSessionUserId();
225
-        iF ($sessionUserId === null) {
226
-            return;
227
-        }
228
-
229
-        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
230
-        $currentUser = User::getById($sessionUserId, $database);
231
-
232
-        if ($currentUser === false) {
233
-            // Umm... this user has a session cookie with a userId set, but no user exists...
234
-            Session::restart();
235
-
236
-            $currentUser = User::getCurrent($database);
237
-        }
238
-
239
-        if ($currentUser->getForceLogout()) {
240
-            Session::restart();
241
-
242
-            $currentUser->setForceLogout(false);
243
-            $currentUser->save();
244
-        }
245
-    }
246
-
247
-    public function isPublic()
248
-    {
249
-        return $this->isPublic;
250
-    }
251
-
252
-    public function setPublic($isPublic)
253
-    {
254
-        $this->isPublic = $isPublic;
255
-    }
35
+	/**
36
+	 * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
37
+	 *                                    routers and hence different URL mappings
38
+	 */
39
+	private $requestRouter;
40
+	/**
41
+	 * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
42
+	 */
43
+	private $isPublic = false;
44
+
45
+	/**
46
+	 * WebStart constructor.
47
+	 *
48
+	 * @param SiteConfiguration $configuration The site configuration
49
+	 * @param IRequestRouter    $router        The request router to use
50
+	 */
51
+	public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
52
+	{
53
+		parent::__construct($configuration);
54
+
55
+		$this->requestRouter = $router;
56
+	}
57
+
58
+	/**
59
+	 * @param ITask             $page
60
+	 * @param SiteConfiguration $siteConfiguration
61
+	 * @param PdoDatabase       $database
62
+	 * @param PdoDatabase       $notificationsDatabase
63
+	 *
64
+	 * @return void
65
+	 */
66
+	protected function setupHelpers(
67
+		ITask $page,
68
+		SiteConfiguration $siteConfiguration,
69
+		PdoDatabase $database,
70
+		PdoDatabase $notificationsDatabase = null
71
+	) {
72
+		parent::setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
73
+
74
+		if ($page instanceof PageBase) {
75
+			$page->setTokenManager(new TokenManager());
76
+			$page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
77
+
78
+			if ($page instanceof InternalPageBase) {
79
+				$page->setTypeAheadHelper(new TypeAheadHelper());
80
+
81
+				$identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration,
82
+					$database);
83
+				$page->setIdentificationVerifier($identificationVerifier);
84
+
85
+				$page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));
86
+
87
+				if ($siteConfiguration->getTitleBlacklistEnabled()) {
88
+					$page->setBlacklistHelper(new FakeBlacklistHelper());
89
+				}
90
+				else {
91
+					$page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(),
92
+						$siteConfiguration->getMediawikiWebServiceEndpoint()));
93
+				}
94
+			}
95
+		}
96
+	}
97
+
98
+	/**
99
+	 * Application entry point.
100
+	 *
101
+	 * Sets up the environment and runs the application, performing any global cleanup operations when done.
102
+	 */
103
+	public function run()
104
+	{
105
+		try {
106
+			if ($this->setupEnvironment()) {
107
+				$this->main();
108
+			}
109
+		}
110
+		catch (EnvironmentException $ex) {
111
+			ob_end_clean();
112
+			print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
113
+		}
114
+		catch (ReadableException $ex) {
115
+			ob_end_clean();
116
+			print $ex->getReadableError();
117
+		}
118
+		finally {
119
+			$this->cleanupEnvironment();
120
+		}
121
+	}
122
+
123
+	/**
124
+	 * Environment setup
125
+	 *
126
+	 * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
127
+	 * and shut down prematurely.
128
+	 *
129
+	 * @return bool
130
+	 * @throws EnvironmentException
131
+	 */
132
+	protected function setupEnvironment()
133
+	{
134
+		// initialise global exception handler
135
+		set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
136
+		set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
137
+
138
+		// start output buffering if necessary
139
+		if (ob_get_level() === 0) {
140
+			ob_start();
141
+		}
142
+
143
+		// initialise super-global providers
144
+		WebRequest::setGlobalStateProvider(new GlobalStateProvider());
145
+
146
+		if (Offline::isOffline()) {
147
+			print Offline::getOfflineMessage($this->isPublic());
148
+			ob_end_flush();
149
+
150
+			return false;
151
+		}
152
+
153
+		// Call parent setup
154
+		if (!parent::setupEnvironment()) {
155
+			return false;
156
+		}
157
+
158
+		// Start up sessions
159
+		Session::start();
160
+
161
+		// Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
162
+		// get the current user cached.
163
+		// I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
164
+		// session I suppose.
165
+		$this->checkForceLogout();
166
+
167
+		// environment initialised!
168
+		return true;
169
+	}
170
+
171
+	/**
172
+	 * Main application logic
173
+	 */
174
+	protected function main()
175
+	{
176
+		// Get the right route for the request
177
+		$page = $this->requestRouter->route();
178
+
179
+		$siteConfiguration = $this->getConfiguration();
180
+		$database = PdoDatabase::getDatabaseConnection('acc');
181
+
182
+		if ($siteConfiguration->getIrcNotificationsEnabled()) {
183
+			$notificationsDatabase = PdoDatabase::getDatabaseConnection('notifications');
184
+		}
185
+		else {
186
+			// @todo federated table here?
187
+			$notificationsDatabase = $database;
188
+		}
189
+
190
+		$this->setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
191
+
192
+		/* @todo Remove this global statement! It's here for User.php, which does far more than it should. */
193
+		global $oauthProtocolHelper;
194
+		$oauthProtocolHelper = $page->getOAuthProtocolHelper();
195
+
196
+		/* @todo Remove this global statement! It's here for Request.php, which does far more than it should. */
197
+		global $globalXffTrustProvider;
198
+		$globalXffTrustProvider = $page->getXffTrustProvider();
199
+
200
+		// run the route code for the request.
201
+		$page->execute();
202
+	}
203
+
204
+	/**
205
+	 * Any cleanup tasks should go here
206
+	 *
207
+	 * Note that we need to be very careful here, as exceptions may have been thrown and handled.
208
+	 * This should *only* be for cleaning up, no logic should go here.
209
+	 */
210
+	protected function cleanupEnvironment()
211
+	{
212
+		// Clean up anything we splurged after sending the page.
213
+		if (ob_get_level() > 0) {
214
+			for ($i = ob_get_level(); $i > 0; $i--) {
215
+				ob_end_clean();
216
+			}
217
+		}
218
+	}
219
+
220
+	private function checkForceLogout()
221
+	{
222
+		$database = PdoDatabase::getDatabaseConnection('acc');
223
+
224
+		$sessionUserId = WebRequest::getSessionUserId();
225
+		iF ($sessionUserId === null) {
226
+			return;
227
+		}
228
+
229
+		// Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
230
+		$currentUser = User::getById($sessionUserId, $database);
231
+
232
+		if ($currentUser === false) {
233
+			// Umm... this user has a session cookie with a userId set, but no user exists...
234
+			Session::restart();
235
+
236
+			$currentUser = User::getCurrent($database);
237
+		}
238
+
239
+		if ($currentUser->getForceLogout()) {
240
+			Session::restart();
241
+
242
+			$currentUser->setForceLogout(false);
243
+			$currentUser->save();
244
+		}
245
+	}
246
+
247
+	public function isPublic()
248
+	{
249
+		return $this->isPublic;
250
+	}
251
+
252
+	public function setPublic($isPublic)
253
+	{
254
+		$this->isPublic = $isPublic;
255
+	}
256 256
 }
Please login to merge, or discard this patch.
includes/Helpers/OAuthUserHelper.php 2 patches
Indentation   +417 added lines, -417 removed lines patch added patch discarded remove patch
@@ -22,425 +22,425 @@
 block discarded – undo
22 22
 
23 23
 class OAuthUserHelper implements IMediaWikiClient
24 24
 {
25
-    const TOKEN_REQUEST = 'request';
26
-    const TOKEN_ACCESS = 'access';
27
-    /** @var PDOStatement */
28
-    private static $tokenCountStatement = null;
29
-    /** @var PDOStatement */
30
-    private $getTokenStatement;
31
-    /**
32
-     * @var User
33
-     */
34
-    private $user;
35
-    /**
36
-     * @var PdoDatabase
37
-     */
38
-    private $database;
39
-    /**
40
-     * @var IOAuthProtocolHelper
41
-     */
42
-    private $oauthProtocolHelper;
43
-    /**
44
-     * @var bool|null Is the user linked to OAuth
45
-     */
46
-    private $linked;
47
-    private $partiallyLinked;
48
-    /** @var OAuthToken */
49
-    private $accessToken;
50
-    /** @var bool */
51
-    private $accessTokenLoaded = false;
52
-    /**
53
-     * @var OAuthIdentity
54
-     */
55
-    private $identity = null;
56
-    /**
57
-     * @var bool
58
-     */
59
-    private $identityLoaded = false;
60
-    /**
61
-     * @var SiteConfiguration
62
-     */
63
-    private $siteConfiguration;
64
-
65
-    #region Static methods
66
-    public static function findUserByRequestToken($requestToken, PdoDatabase $database)
67
-    {
68
-        $statement = $database->prepare(<<<'SQL'
25
+	const TOKEN_REQUEST = 'request';
26
+	const TOKEN_ACCESS = 'access';
27
+	/** @var PDOStatement */
28
+	private static $tokenCountStatement = null;
29
+	/** @var PDOStatement */
30
+	private $getTokenStatement;
31
+	/**
32
+	 * @var User
33
+	 */
34
+	private $user;
35
+	/**
36
+	 * @var PdoDatabase
37
+	 */
38
+	private $database;
39
+	/**
40
+	 * @var IOAuthProtocolHelper
41
+	 */
42
+	private $oauthProtocolHelper;
43
+	/**
44
+	 * @var bool|null Is the user linked to OAuth
45
+	 */
46
+	private $linked;
47
+	private $partiallyLinked;
48
+	/** @var OAuthToken */
49
+	private $accessToken;
50
+	/** @var bool */
51
+	private $accessTokenLoaded = false;
52
+	/**
53
+	 * @var OAuthIdentity
54
+	 */
55
+	private $identity = null;
56
+	/**
57
+	 * @var bool
58
+	 */
59
+	private $identityLoaded = false;
60
+	/**
61
+	 * @var SiteConfiguration
62
+	 */
63
+	private $siteConfiguration;
64
+
65
+	#region Static methods
66
+	public static function findUserByRequestToken($requestToken, PdoDatabase $database)
67
+	{
68
+		$statement = $database->prepare(<<<'SQL'
69 69
             SELECT u.* FROM user u 
70 70
             INNER JOIN oauthtoken t ON t.user = u.id 
71 71
             WHERE t.type = :type AND t.token = :token
72 72
 SQL
73
-        );
74
-        $statement->execute(array(':type' => self::TOKEN_REQUEST, ':token' => $requestToken));
75
-
76
-        /** @var User $user */
77
-        $user = $statement->fetchObject(User::class);
78
-        $statement->closeCursor();
79
-
80
-        if ($user === false) {
81
-            throw new ApplicationLogicException('Token not found in store, please try again');
82
-        }
83
-
84
-        $user->setDatabase($database);
85
-
86
-        return $user;
87
-    }
88
-
89
-    public static function userIsFullyLinked(User $user, PdoDatabase $database = null)
90
-    {
91
-        if (self::$tokenCountStatement === null && $database === null) {
92
-            throw new ApplicationLogicException('Static link request without initialised statement');
93
-        }
94
-
95
-        return self::runTokenCount($user->getId(), $database, self::TOKEN_ACCESS);
96
-    }
97
-
98
-    public static function userIsPartiallyLinked(User $user, PdoDatabase $database = null)
99
-    {
100
-        if (self::$tokenCountStatement === null && $database === null) {
101
-            throw new ApplicationLogicException('Static link request without initialised statement');
102
-        }
103
-
104
-        if (self::userIsFullyLinked($user, $database)) {
105
-            return false;
106
-        }
107
-
108
-        return self::runTokenCount($user->getId(), $database, self::TOKEN_REQUEST)
109
-            || $user->getOnWikiName() == null;
110
-    }
111
-
112
-    /**
113
-     * @param PdoDatabase $database
114
-     */
115
-    public static function prepareTokenCountStatement(PdoDatabase $database)
116
-    {
117
-        if (self::$tokenCountStatement === null) {
118
-            self::$tokenCountStatement = $database->prepare('SELECT COUNT(*) FROM oauthtoken WHERE user = :user AND type = :type');
119
-        }
120
-    }
121
-
122
-    private static function runTokenCount($userId, $database, $tokenType)
123
-    {
124
-        if (self::$tokenCountStatement === null) {
125
-            self::prepareTokenCountStatement($database);
126
-        }
127
-
128
-        self::$tokenCountStatement->execute(array(
129
-            ':user' => $userId,
130
-            ':type' => $tokenType,
131
-        ));
132
-
133
-        $tokenCount = self::$tokenCountStatement->fetchColumn();
134
-        $linked = $tokenCount > 0;
135
-        self::$tokenCountStatement->closeCursor();
136
-
137
-        return $linked;
138
-    }
139
-
140
-    #endregion Static methods
141
-
142
-    /**
143
-     * OAuthUserHelper constructor.
144
-     *
145
-     * @param User                 $user
146
-     * @param PdoDatabase          $database
147
-     * @param IOAuthProtocolHelper $oauthProtocolHelper
148
-     * @param SiteConfiguration    $siteConfiguration
149
-     */
150
-    public function __construct(
151
-        User $user,
152
-        PdoDatabase $database,
153
-        IOAuthProtocolHelper $oauthProtocolHelper,
154
-        SiteConfiguration $siteConfiguration
155
-    ) {
156
-        $this->user = $user;
157
-        $this->database = $database;
158
-        $this->oauthProtocolHelper = $oauthProtocolHelper;
159
-
160
-        $this->linked = null;
161
-        $this->partiallyLinked = null;
162
-        $this->siteConfiguration = $siteConfiguration;
163
-
164
-        self::prepareTokenCountStatement($database);
165
-        $this->getTokenStatement = $this->database->prepare('SELECT * FROM oauthtoken WHERE user = :user AND type = :type');
166
-    }
167
-
168
-    /**
169
-     * Determines if the user is fully connected to OAuth.
170
-     *
171
-     * @return bool
172
-     */
173
-    public function isFullyLinked()
174
-    {
175
-        if ($this->linked === null) {
176
-            $this->linked = self::userIsFullyLinked($this->user, $this->database);
177
-        }
178
-
179
-        return $this->linked;
180
-    }
181
-
182
-    /**
183
-     * Attempts to figure out if a user is partially linked to OAuth, and therefore needs to complete the OAuth
184
-     * procedure before configuring.
185
-     * @return bool
186
-     */
187
-    public function isPartiallyLinked()
188
-    {
189
-        if ($this->partiallyLinked === null) {
190
-            $this->partiallyLinked = self::userIsPartiallyLinked($this->user, $this->database);
191
-        }
192
-
193
-        return $this->partiallyLinked;
194
-    }
195
-
196
-    public function canCreateAccount() {
197
-        return $this->isFullyLinked()
198
-            && $this->getIdentity(true)->getGrantBasic()
199
-            && $this->getIdentity(true)->getGrantHighVolume()
200
-            && $this->getIdentity(true)->getGrantCreateAccount();
201
-    }
202
-
203
-    public function canWelcome() {
204
-        return $this->isFullyLinked()
205
-            && $this->getIdentity(true)->getGrantBasic()
206
-            && $this->getIdentity(true)->getGrantHighVolume()
207
-            && $this->getIdentity(true)->getGrantCreateEditMovePage();
208
-    }
209
-
210
-    /**
211
-     * @throws OAuthException
212
-     */
213
-    public function refreshIdentity()
214
-    {
215
-        $this->loadIdentity();
216
-
217
-        if ($this->identity === null) {
218
-            $this->identity = new OAuthIdentity();
219
-            $this->identity->setUserId($this->user->getId());
220
-            $this->identity->setDatabase($this->database);
221
-        }
222
-
223
-        $token = $this->loadAccessToken();
224
-
225
-        $rawTicket = $this->oauthProtocolHelper->getIdentityTicket($token->getToken(), $token->getSecret());
226
-
227
-        $this->identity->populate($rawTicket);
228
-
229
-        if (!$this->identityIsValid()) {
230
-            throw new OAuthException('Identity ticket is not valid!');
231
-        }
232
-
233
-        $this->identity->save();
234
-
235
-        $this->user->setOnWikiName($this->identity->getUsername());
236
-        $this->user->save();
237
-    }
238
-
239
-    public function getRequestToken()
240
-    {
241
-        $token = $this->oauthProtocolHelper->getRequestToken();
242
-
243
-        $this->partiallyLinked = true;
244
-        $this->linked = false;
245
-
246
-        $this->database
247
-            ->prepare('DELETE FROM oauthtoken WHERE user = :user AND type = :type')
248
-            ->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
249
-
250
-        $this->database
251
-            ->prepare('INSERT INTO oauthtoken (user, type, token, secret, expiry) VALUES (:user, :type, :token, :secret, DATE_ADD(NOW(), INTERVAL 1 DAY))')
252
-            ->execute(array(
253
-                ':user'   => $this->user->getId(),
254
-                ':type'   => self::TOKEN_REQUEST,
255
-                ':token'  => $token->key,
256
-                ':secret' => $token->secret,
257
-            ));
258
-
259
-        return $this->oauthProtocolHelper->getAuthoriseUrl($token->key);
260
-    }
261
-
262
-    public function completeHandshake($verificationToken)
263
-    {
264
-        $this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
265
-
266
-        /** @var OAuthToken $token */
267
-        $token = $this->getTokenStatement->fetchObject(OAuthToken::class);
268
-        $this->getTokenStatement->closeCursor();
269
-
270
-        if ($token === false) {
271
-            throw new ApplicationLogicException('Cannot find request token');
272
-        }
273
-
274
-        $token->setDatabase($this->database);
275
-
276
-        $accessToken = $this->oauthProtocolHelper->callbackCompleted($token->getToken(), $token->getSecret(),
277
-            $verificationToken);
278
-
279
-        $clearStatement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :u AND type = :t');
280
-        $clearStatement->execute(array(':u' => $this->user->getId(), ':t' => self::TOKEN_ACCESS));
281
-
282
-        $token->setToken($accessToken->key);
283
-        $token->setSecret($accessToken->secret);
284
-        $token->setType(self::TOKEN_ACCESS);
285
-        $token->setExpiry(null);
286
-        $token->save();
287
-
288
-        $this->partiallyLinked = false;
289
-        $this->linked = true;
290
-
291
-        $this->refreshIdentity();
292
-    }
293
-
294
-    public function detach()
295
-    {
296
-        $this->loadIdentity();
297
-
298
-        $this->identity->delete();
299
-        $statement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :user');
300
-        $statement->execute(array(':user' => $this->user->getId()));
301
-
302
-        $this->identity = null;
303
-        $this->linked = false;
304
-        $this->partiallyLinked = false;
305
-    }
306
-
307
-    /**
308
-     * @param bool $expiredOk
309
-     *
310
-     * @return OAuthIdentity
311
-     * @throws OAuthException
312
-     */
313
-    public function getIdentity($expiredOk = false)
314
-    {
315
-        $this->loadIdentity();
316
-
317
-        if (!$this->identityIsValid($expiredOk)) {
318
-            throw new OAuthException('Stored identity is not valid.');
319
-        }
320
-
321
-        return $this->identity;
322
-    }
323
-
324
-    public function doApiCall($params, $method)
325
-    {
326
-        // Ensure we're logged in
327
-        $params['assert'] = 'user';
328
-
329
-        $token = $this->loadAccessToken();
330
-        return $this->oauthProtocolHelper->apiCall($params, $token->getToken(), $token->getSecret(), $method);
331
-    }
332
-
333
-    /**
334
-     * @param bool $expiredOk
335
-     *
336
-     * @return bool
337
-     */
338
-    private function identityIsValid($expiredOk = false)
339
-    {
340
-        $this->loadIdentity();
341
-
342
-        if ($this->identity === null) {
343
-            return false;
344
-        }
345
-
346
-        if ($this->identity->getIssuedAtTime() === false
347
-            || $this->identity->getExpirationTime() === false
348
-            || $this->identity->getAudience() === false
349
-            || $this->identity->getIssuer() === false
350
-        ) {
351
-            // this isn't populated properly.
352
-            return false;
353
-        }
354
-
355
-        $issue = DateTimeImmutable::createFromFormat("U", $this->identity->getIssuedAtTime());
356
-        $now = new DateTimeImmutable();
357
-
358
-        if ($issue > $now) {
359
-            // wat.
360
-            return false;
361
-        }
362
-
363
-        if ($this->identityExpired() && !$expiredOk) {
364
-            // soz.
365
-            return false;
366
-        }
367
-
368
-        if ($this->identity->getAudience() !== $this->siteConfiguration->getOAuthConsumerToken()) {
369
-            // token not issued for us
370
-            return false;
371
-        }
372
-
373
-        if ($this->identity->getIssuer() !== $this->siteConfiguration->getOauthMediaWikiCanonicalServer()) {
374
-            // token not issued by the right person
375
-            return false;
376
-        }
377
-
378
-        // can't find a reason to not trust it
379
-        return true;
380
-    }
381
-
382
-    /**
383
-     * @return bool
384
-     */
385
-    public function identityExpired()
386
-    {
387
-        // allowed max age
388
-        $gracePeriod = $this->siteConfiguration->getOauthIdentityGraceTime();
389
-
390
-        $expiry = DateTimeImmutable::createFromFormat("U", $this->identity->getExpirationTime());
391
-        $graceExpiry = $expiry->modify($gracePeriod);
392
-        $now = new DateTimeImmutable();
393
-
394
-        return $graceExpiry < $now;
395
-    }
396
-
397
-    /**
398
-     * Loads the OAuth identity from the database for the current user.
399
-     */
400
-    private function loadIdentity()
401
-    {
402
-        if ($this->identityLoaded) {
403
-            return;
404
-        }
405
-
406
-        $statement = $this->database->prepare('SELECT * FROM oauthidentity WHERE user = :user');
407
-        $statement->execute(array(':user' => $this->user->getId()));
408
-        /** @var OAuthIdentity $obj */
409
-        $obj = $statement->fetchObject(OAuthIdentity::class);
410
-
411
-        if ($obj === false) {
412
-            // failed to load identity.
413
-            $this->identityLoaded = true;
414
-            $this->identity = null;
415
-
416
-            return;
417
-        }
418
-
419
-        $obj->setDatabase($this->database);
420
-        $this->identityLoaded = true;
421
-        $this->identity = $obj;
422
-    }
423
-
424
-    /**
425
-     * @return OAuthToken
426
-     * @throws OAuthException
427
-     */
428
-    private function loadAccessToken()
429
-    {
430
-        if (!$this->accessTokenLoaded) {
431
-            $this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_ACCESS));
432
-            /** @var OAuthToken $token */
433
-            $token = $this->getTokenStatement->fetchObject(OAuthToken::class);
434
-            $this->getTokenStatement->closeCursor();
435
-
436
-            if ($token === false) {
437
-                throw new OAuthException('Access token not found!');
438
-            }
439
-
440
-            $this->accessToken = $token;
441
-            $this->accessTokenLoaded = true;
442
-        }
443
-
444
-        return $this->accessToken;
445
-    }
73
+		);
74
+		$statement->execute(array(':type' => self::TOKEN_REQUEST, ':token' => $requestToken));
75
+
76
+		/** @var User $user */
77
+		$user = $statement->fetchObject(User::class);
78
+		$statement->closeCursor();
79
+
80
+		if ($user === false) {
81
+			throw new ApplicationLogicException('Token not found in store, please try again');
82
+		}
83
+
84
+		$user->setDatabase($database);
85
+
86
+		return $user;
87
+	}
88
+
89
+	public static function userIsFullyLinked(User $user, PdoDatabase $database = null)
90
+	{
91
+		if (self::$tokenCountStatement === null && $database === null) {
92
+			throw new ApplicationLogicException('Static link request without initialised statement');
93
+		}
94
+
95
+		return self::runTokenCount($user->getId(), $database, self::TOKEN_ACCESS);
96
+	}
97
+
98
+	public static function userIsPartiallyLinked(User $user, PdoDatabase $database = null)
99
+	{
100
+		if (self::$tokenCountStatement === null && $database === null) {
101
+			throw new ApplicationLogicException('Static link request without initialised statement');
102
+		}
103
+
104
+		if (self::userIsFullyLinked($user, $database)) {
105
+			return false;
106
+		}
107
+
108
+		return self::runTokenCount($user->getId(), $database, self::TOKEN_REQUEST)
109
+			|| $user->getOnWikiName() == null;
110
+	}
111
+
112
+	/**
113
+	 * @param PdoDatabase $database
114
+	 */
115
+	public static function prepareTokenCountStatement(PdoDatabase $database)
116
+	{
117
+		if (self::$tokenCountStatement === null) {
118
+			self::$tokenCountStatement = $database->prepare('SELECT COUNT(*) FROM oauthtoken WHERE user = :user AND type = :type');
119
+		}
120
+	}
121
+
122
+	private static function runTokenCount($userId, $database, $tokenType)
123
+	{
124
+		if (self::$tokenCountStatement === null) {
125
+			self::prepareTokenCountStatement($database);
126
+		}
127
+
128
+		self::$tokenCountStatement->execute(array(
129
+			':user' => $userId,
130
+			':type' => $tokenType,
131
+		));
132
+
133
+		$tokenCount = self::$tokenCountStatement->fetchColumn();
134
+		$linked = $tokenCount > 0;
135
+		self::$tokenCountStatement->closeCursor();
136
+
137
+		return $linked;
138
+	}
139
+
140
+	#endregion Static methods
141
+
142
+	/**
143
+	 * OAuthUserHelper constructor.
144
+	 *
145
+	 * @param User                 $user
146
+	 * @param PdoDatabase          $database
147
+	 * @param IOAuthProtocolHelper $oauthProtocolHelper
148
+	 * @param SiteConfiguration    $siteConfiguration
149
+	 */
150
+	public function __construct(
151
+		User $user,
152
+		PdoDatabase $database,
153
+		IOAuthProtocolHelper $oauthProtocolHelper,
154
+		SiteConfiguration $siteConfiguration
155
+	) {
156
+		$this->user = $user;
157
+		$this->database = $database;
158
+		$this->oauthProtocolHelper = $oauthProtocolHelper;
159
+
160
+		$this->linked = null;
161
+		$this->partiallyLinked = null;
162
+		$this->siteConfiguration = $siteConfiguration;
163
+
164
+		self::prepareTokenCountStatement($database);
165
+		$this->getTokenStatement = $this->database->prepare('SELECT * FROM oauthtoken WHERE user = :user AND type = :type');
166
+	}
167
+
168
+	/**
169
+	 * Determines if the user is fully connected to OAuth.
170
+	 *
171
+	 * @return bool
172
+	 */
173
+	public function isFullyLinked()
174
+	{
175
+		if ($this->linked === null) {
176
+			$this->linked = self::userIsFullyLinked($this->user, $this->database);
177
+		}
178
+
179
+		return $this->linked;
180
+	}
181
+
182
+	/**
183
+	 * Attempts to figure out if a user is partially linked to OAuth, and therefore needs to complete the OAuth
184
+	 * procedure before configuring.
185
+	 * @return bool
186
+	 */
187
+	public function isPartiallyLinked()
188
+	{
189
+		if ($this->partiallyLinked === null) {
190
+			$this->partiallyLinked = self::userIsPartiallyLinked($this->user, $this->database);
191
+		}
192
+
193
+		return $this->partiallyLinked;
194
+	}
195
+
196
+	public function canCreateAccount() {
197
+		return $this->isFullyLinked()
198
+			&& $this->getIdentity(true)->getGrantBasic()
199
+			&& $this->getIdentity(true)->getGrantHighVolume()
200
+			&& $this->getIdentity(true)->getGrantCreateAccount();
201
+	}
202
+
203
+	public function canWelcome() {
204
+		return $this->isFullyLinked()
205
+			&& $this->getIdentity(true)->getGrantBasic()
206
+			&& $this->getIdentity(true)->getGrantHighVolume()
207
+			&& $this->getIdentity(true)->getGrantCreateEditMovePage();
208
+	}
209
+
210
+	/**
211
+	 * @throws OAuthException
212
+	 */
213
+	public function refreshIdentity()
214
+	{
215
+		$this->loadIdentity();
216
+
217
+		if ($this->identity === null) {
218
+			$this->identity = new OAuthIdentity();
219
+			$this->identity->setUserId($this->user->getId());
220
+			$this->identity->setDatabase($this->database);
221
+		}
222
+
223
+		$token = $this->loadAccessToken();
224
+
225
+		$rawTicket = $this->oauthProtocolHelper->getIdentityTicket($token->getToken(), $token->getSecret());
226
+
227
+		$this->identity->populate($rawTicket);
228
+
229
+		if (!$this->identityIsValid()) {
230
+			throw new OAuthException('Identity ticket is not valid!');
231
+		}
232
+
233
+		$this->identity->save();
234
+
235
+		$this->user->setOnWikiName($this->identity->getUsername());
236
+		$this->user->save();
237
+	}
238
+
239
+	public function getRequestToken()
240
+	{
241
+		$token = $this->oauthProtocolHelper->getRequestToken();
242
+
243
+		$this->partiallyLinked = true;
244
+		$this->linked = false;
245
+
246
+		$this->database
247
+			->prepare('DELETE FROM oauthtoken WHERE user = :user AND type = :type')
248
+			->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
249
+
250
+		$this->database
251
+			->prepare('INSERT INTO oauthtoken (user, type, token, secret, expiry) VALUES (:user, :type, :token, :secret, DATE_ADD(NOW(), INTERVAL 1 DAY))')
252
+			->execute(array(
253
+				':user'   => $this->user->getId(),
254
+				':type'   => self::TOKEN_REQUEST,
255
+				':token'  => $token->key,
256
+				':secret' => $token->secret,
257
+			));
258
+
259
+		return $this->oauthProtocolHelper->getAuthoriseUrl($token->key);
260
+	}
261
+
262
+	public function completeHandshake($verificationToken)
263
+	{
264
+		$this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
265
+
266
+		/** @var OAuthToken $token */
267
+		$token = $this->getTokenStatement->fetchObject(OAuthToken::class);
268
+		$this->getTokenStatement->closeCursor();
269
+
270
+		if ($token === false) {
271
+			throw new ApplicationLogicException('Cannot find request token');
272
+		}
273
+
274
+		$token->setDatabase($this->database);
275
+
276
+		$accessToken = $this->oauthProtocolHelper->callbackCompleted($token->getToken(), $token->getSecret(),
277
+			$verificationToken);
278
+
279
+		$clearStatement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :u AND type = :t');
280
+		$clearStatement->execute(array(':u' => $this->user->getId(), ':t' => self::TOKEN_ACCESS));
281
+
282
+		$token->setToken($accessToken->key);
283
+		$token->setSecret($accessToken->secret);
284
+		$token->setType(self::TOKEN_ACCESS);
285
+		$token->setExpiry(null);
286
+		$token->save();
287
+
288
+		$this->partiallyLinked = false;
289
+		$this->linked = true;
290
+
291
+		$this->refreshIdentity();
292
+	}
293
+
294
+	public function detach()
295
+	{
296
+		$this->loadIdentity();
297
+
298
+		$this->identity->delete();
299
+		$statement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :user');
300
+		$statement->execute(array(':user' => $this->user->getId()));
301
+
302
+		$this->identity = null;
303
+		$this->linked = false;
304
+		$this->partiallyLinked = false;
305
+	}
306
+
307
+	/**
308
+	 * @param bool $expiredOk
309
+	 *
310
+	 * @return OAuthIdentity
311
+	 * @throws OAuthException
312
+	 */
313
+	public function getIdentity($expiredOk = false)
314
+	{
315
+		$this->loadIdentity();
316
+
317
+		if (!$this->identityIsValid($expiredOk)) {
318
+			throw new OAuthException('Stored identity is not valid.');
319
+		}
320
+
321
+		return $this->identity;
322
+	}
323
+
324
+	public function doApiCall($params, $method)
325
+	{
326
+		// Ensure we're logged in
327
+		$params['assert'] = 'user';
328
+
329
+		$token = $this->loadAccessToken();
330
+		return $this->oauthProtocolHelper->apiCall($params, $token->getToken(), $token->getSecret(), $method);
331
+	}
332
+
333
+	/**
334
+	 * @param bool $expiredOk
335
+	 *
336
+	 * @return bool
337
+	 */
338
+	private function identityIsValid($expiredOk = false)
339
+	{
340
+		$this->loadIdentity();
341
+
342
+		if ($this->identity === null) {
343
+			return false;
344
+		}
345
+
346
+		if ($this->identity->getIssuedAtTime() === false
347
+			|| $this->identity->getExpirationTime() === false
348
+			|| $this->identity->getAudience() === false
349
+			|| $this->identity->getIssuer() === false
350
+		) {
351
+			// this isn't populated properly.
352
+			return false;
353
+		}
354
+
355
+		$issue = DateTimeImmutable::createFromFormat("U", $this->identity->getIssuedAtTime());
356
+		$now = new DateTimeImmutable();
357
+
358
+		if ($issue > $now) {
359
+			// wat.
360
+			return false;
361
+		}
362
+
363
+		if ($this->identityExpired() && !$expiredOk) {
364
+			// soz.
365
+			return false;
366
+		}
367
+
368
+		if ($this->identity->getAudience() !== $this->siteConfiguration->getOAuthConsumerToken()) {
369
+			// token not issued for us
370
+			return false;
371
+		}
372
+
373
+		if ($this->identity->getIssuer() !== $this->siteConfiguration->getOauthMediaWikiCanonicalServer()) {
374
+			// token not issued by the right person
375
+			return false;
376
+		}
377
+
378
+		// can't find a reason to not trust it
379
+		return true;
380
+	}
381
+
382
+	/**
383
+	 * @return bool
384
+	 */
385
+	public function identityExpired()
386
+	{
387
+		// allowed max age
388
+		$gracePeriod = $this->siteConfiguration->getOauthIdentityGraceTime();
389
+
390
+		$expiry = DateTimeImmutable::createFromFormat("U", $this->identity->getExpirationTime());
391
+		$graceExpiry = $expiry->modify($gracePeriod);
392
+		$now = new DateTimeImmutable();
393
+
394
+		return $graceExpiry < $now;
395
+	}
396
+
397
+	/**
398
+	 * Loads the OAuth identity from the database for the current user.
399
+	 */
400
+	private function loadIdentity()
401
+	{
402
+		if ($this->identityLoaded) {
403
+			return;
404
+		}
405
+
406
+		$statement = $this->database->prepare('SELECT * FROM oauthidentity WHERE user = :user');
407
+		$statement->execute(array(':user' => $this->user->getId()));
408
+		/** @var OAuthIdentity $obj */
409
+		$obj = $statement->fetchObject(OAuthIdentity::class);
410
+
411
+		if ($obj === false) {
412
+			// failed to load identity.
413
+			$this->identityLoaded = true;
414
+			$this->identity = null;
415
+
416
+			return;
417
+		}
418
+
419
+		$obj->setDatabase($this->database);
420
+		$this->identityLoaded = true;
421
+		$this->identity = $obj;
422
+	}
423
+
424
+	/**
425
+	 * @return OAuthToken
426
+	 * @throws OAuthException
427
+	 */
428
+	private function loadAccessToken()
429
+	{
430
+		if (!$this->accessTokenLoaded) {
431
+			$this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_ACCESS));
432
+			/** @var OAuthToken $token */
433
+			$token = $this->getTokenStatement->fetchObject(OAuthToken::class);
434
+			$this->getTokenStatement->closeCursor();
435
+
436
+			if ($token === false) {
437
+				throw new OAuthException('Access token not found!');
438
+			}
439
+
440
+			$this->accessToken = $token;
441
+			$this->accessTokenLoaded = true;
442
+		}
443
+
444
+		return $this->accessToken;
445
+	}
446 446
 }
Please login to merge, or discard this patch.
Braces   +4 added lines, -2 removed lines patch added patch discarded remove patch
@@ -193,14 +193,16 @@
 block discarded – undo
193 193
         return $this->partiallyLinked;
194 194
     }
195 195
 
196
-    public function canCreateAccount() {
196
+    public function canCreateAccount()
197
+    {
197 198
         return $this->isFullyLinked()
198 199
             && $this->getIdentity(true)->getGrantBasic()
199 200
             && $this->getIdentity(true)->getGrantHighVolume()
200 201
             && $this->getIdentity(true)->getGrantCreateAccount();
201 202
     }
202 203
 
203
-    public function canWelcome() {
204
+    public function canWelcome()
205
+    {
204 206
         return $this->isFullyLinked()
205 207
             && $this->getIdentity(true)->getGrantBasic()
206 208
             && $this->getIdentity(true)->getGrantHighVolume()
Please login to merge, or discard this patch.
includes/Tasks/InternalPageBase.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -23,228 +23,228 @@
 block discarded – undo
23 23
 
24 24
 abstract class InternalPageBase extends PageBase
25 25
 {
26
-    use NavigationMenuAccessControl;
27
-
28
-    /** @var IdentificationVerifier */
29
-    private $identificationVerifier;
30
-    /** @var ITypeAheadHelper */
31
-    private $typeAheadHelper;
32
-    /** @var SecurityManager */
33
-    private $securityManager;
34
-    /** @var IBlacklistHelper */
35
-    private $blacklistHelper;
36
-
37
-    /**
38
-     * @return ITypeAheadHelper
39
-     */
40
-    public function getTypeAheadHelper()
41
-    {
42
-        return $this->typeAheadHelper;
43
-    }
44
-
45
-    /**
46
-     * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
-     *
48
-     * @param IdentificationVerifier $identificationVerifier
49
-     *
50
-     * @return void
51
-     */
52
-    public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
-    {
54
-        $this->identificationVerifier = $identificationVerifier;
55
-    }
56
-
57
-    /**
58
-     * @param ITypeAheadHelper $typeAheadHelper
59
-     */
60
-    public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
-    {
62
-        $this->typeAheadHelper = $typeAheadHelper;
63
-    }
64
-
65
-    /**
66
-     * Runs the page code
67
-     *
68
-     * @throws Exception
69
-     * @category Security-Critical
70
-     */
71
-    final public function execute()
72
-    {
73
-        if ($this->getRouteName() === null) {
74
-            throw new Exception("Request is unrouted.");
75
-        }
76
-
77
-        if ($this->getSiteConfiguration() === null) {
78
-            throw new Exception("Page has no configuration!");
79
-        }
80
-
81
-        $this->setupPage();
82
-
83
-        $this->touchUserLastActive();
84
-
85
-        $currentUser = User::getCurrent($this->getDatabase());
86
-
87
-        // Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
-        if (!$this->isProtectedPage()) {
89
-            // This page is /not/ a protected page, as such we can just run it.
90
-            $this->runPage();
91
-
92
-            return;
93
-        }
94
-
95
-        // Security barrier.
96
-        //
97
-        // This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
-        // away for us
99
-        $securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
-        if ($securityResult === SecurityManager::ALLOWED) {
101
-            // We're allowed to run the page, so let's run it.
102
-            $this->runPage();
103
-        }
104
-        else {
105
-            $this->handleAccessDenied($securityResult);
106
-
107
-            // Send the headers
108
-            $this->sendResponseHeaders();
109
-        }
110
-    }
111
-
112
-    /**
113
-     * Performs final tasks needed before rendering the page.
114
-     */
115
-    final public function finalisePage()
116
-    {
117
-        parent::finalisePage();
118
-
119
-        $database = $this->getDatabase();
120
-        $currentUser = User::getCurrent($database);
121
-
122
-        if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
-            $siteNoticeText = SiteNotice::get($this->getDatabase());
124
-            $this->assign('siteNoticeText', $siteNoticeText);
125
-        }
126
-
127
-        if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
-            $sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
-            $statement = $database->query($sql);
130
-            $activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
-            $this->assign('onlineusers', $activeUsers);
132
-        }
133
-
134
-        $this->setupNavMenuAccess($currentUser);
135
-    }
136
-
137
-    /**
138
-     * Configures whether the page respects roles or not. You probably want this to return true.
139
-     *
140
-     * Set to false for public pages. You probably want this to return true.
141
-     *
142
-     * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
-     * on this page, so you probably want this to return true.
144
-     *
145
-     * @return bool
146
-     * @category Security-Critical
147
-     */
148
-    protected function isProtectedPage()
149
-    {
150
-        return true;
151
-    }
152
-
153
-    protected function handleAccessDenied($denyReason)
154
-    {
155
-        $currentUser = User::getCurrent($this->getDatabase());
156
-
157
-        // Not allowed to access this resource.
158
-        // Firstly, let's check if we're even logged in.
159
-        if ($currentUser->isCommunityUser()) {
160
-            // Not logged in, redirect to login page
161
-            WebRequest::setPostLoginRedirect();
162
-            $this->redirect("login");
163
-
164
-            return;
165
-        }
166
-        else {
167
-            // Decide whether this was a rights failure, or an identification failure.
168
-
169
-            if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
-                // Not identified
171
-                throw new NotIdentifiedException($this->getSecurityManager());
172
-            }
173
-            elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
-                // Nope, plain old access denied
175
-                throw new AccessDeniedException($this->getSecurityManager());
176
-            }
177
-            else {
178
-                throw new Exception('Unknown response from security manager.');
179
-            }
180
-        }
181
-    }
182
-
183
-    /**
184
-     * Tests the security barrier for a specified action.
185
-     *
186
-     * Don't use within templates
187
-     *
188
-     * @param string      $action
189
-     *
190
-     * @param User        $user
191
-     * @param null|string $pageName
192
-     *
193
-     * @return bool
194
-     * @category Security-Critical
195
-     */
196
-    final public function barrierTest($action, User $user, $pageName = null)
197
-    {
198
-        $page = get_called_class();
199
-        if ($pageName !== null) {
200
-            $page = $pageName;
201
-        }
202
-
203
-        $securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
-
205
-        return $securityResult === SecurityManager::ALLOWED;
206
-    }
207
-
208
-    /**
209
-     * Updates the lastactive timestamp
210
-     */
211
-    private function touchUserLastActive()
212
-    {
213
-        if (WebRequest::getSessionUserId() !== null) {
214
-            $query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
-            $this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
-        }
217
-    }
218
-
219
-    /**
220
-     * @return SecurityManager
221
-     */
222
-    public function getSecurityManager()
223
-    {
224
-        return $this->securityManager;
225
-    }
226
-
227
-    /**
228
-     * @param SecurityManager $securityManager
229
-     */
230
-    public function setSecurityManager(SecurityManager $securityManager)
231
-    {
232
-        $this->securityManager = $securityManager;
233
-    }
234
-
235
-    /**
236
-     * @return IBlacklistHelper
237
-     */
238
-    public function getBlacklistHelper()
239
-    {
240
-        return $this->blacklistHelper;
241
-    }
242
-
243
-    /**
244
-     * @param IBlacklistHelper $blacklistHelper
245
-     */
246
-    public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
-    {
248
-        $this->blacklistHelper = $blacklistHelper;
249
-    }
26
+	use NavigationMenuAccessControl;
27
+
28
+	/** @var IdentificationVerifier */
29
+	private $identificationVerifier;
30
+	/** @var ITypeAheadHelper */
31
+	private $typeAheadHelper;
32
+	/** @var SecurityManager */
33
+	private $securityManager;
34
+	/** @var IBlacklistHelper */
35
+	private $blacklistHelper;
36
+
37
+	/**
38
+	 * @return ITypeAheadHelper
39
+	 */
40
+	public function getTypeAheadHelper()
41
+	{
42
+		return $this->typeAheadHelper;
43
+	}
44
+
45
+	/**
46
+	 * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
+	 *
48
+	 * @param IdentificationVerifier $identificationVerifier
49
+	 *
50
+	 * @return void
51
+	 */
52
+	public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
+	{
54
+		$this->identificationVerifier = $identificationVerifier;
55
+	}
56
+
57
+	/**
58
+	 * @param ITypeAheadHelper $typeAheadHelper
59
+	 */
60
+	public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
+	{
62
+		$this->typeAheadHelper = $typeAheadHelper;
63
+	}
64
+
65
+	/**
66
+	 * Runs the page code
67
+	 *
68
+	 * @throws Exception
69
+	 * @category Security-Critical
70
+	 */
71
+	final public function execute()
72
+	{
73
+		if ($this->getRouteName() === null) {
74
+			throw new Exception("Request is unrouted.");
75
+		}
76
+
77
+		if ($this->getSiteConfiguration() === null) {
78
+			throw new Exception("Page has no configuration!");
79
+		}
80
+
81
+		$this->setupPage();
82
+
83
+		$this->touchUserLastActive();
84
+
85
+		$currentUser = User::getCurrent($this->getDatabase());
86
+
87
+		// Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
+		if (!$this->isProtectedPage()) {
89
+			// This page is /not/ a protected page, as such we can just run it.
90
+			$this->runPage();
91
+
92
+			return;
93
+		}
94
+
95
+		// Security barrier.
96
+		//
97
+		// This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
+		// away for us
99
+		$securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
+		if ($securityResult === SecurityManager::ALLOWED) {
101
+			// We're allowed to run the page, so let's run it.
102
+			$this->runPage();
103
+		}
104
+		else {
105
+			$this->handleAccessDenied($securityResult);
106
+
107
+			// Send the headers
108
+			$this->sendResponseHeaders();
109
+		}
110
+	}
111
+
112
+	/**
113
+	 * Performs final tasks needed before rendering the page.
114
+	 */
115
+	final public function finalisePage()
116
+	{
117
+		parent::finalisePage();
118
+
119
+		$database = $this->getDatabase();
120
+		$currentUser = User::getCurrent($database);
121
+
122
+		if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
+			$siteNoticeText = SiteNotice::get($this->getDatabase());
124
+			$this->assign('siteNoticeText', $siteNoticeText);
125
+		}
126
+
127
+		if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
+			$sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
+			$statement = $database->query($sql);
130
+			$activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
+			$this->assign('onlineusers', $activeUsers);
132
+		}
133
+
134
+		$this->setupNavMenuAccess($currentUser);
135
+	}
136
+
137
+	/**
138
+	 * Configures whether the page respects roles or not. You probably want this to return true.
139
+	 *
140
+	 * Set to false for public pages. You probably want this to return true.
141
+	 *
142
+	 * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
+	 * on this page, so you probably want this to return true.
144
+	 *
145
+	 * @return bool
146
+	 * @category Security-Critical
147
+	 */
148
+	protected function isProtectedPage()
149
+	{
150
+		return true;
151
+	}
152
+
153
+	protected function handleAccessDenied($denyReason)
154
+	{
155
+		$currentUser = User::getCurrent($this->getDatabase());
156
+
157
+		// Not allowed to access this resource.
158
+		// Firstly, let's check if we're even logged in.
159
+		if ($currentUser->isCommunityUser()) {
160
+			// Not logged in, redirect to login page
161
+			WebRequest::setPostLoginRedirect();
162
+			$this->redirect("login");
163
+
164
+			return;
165
+		}
166
+		else {
167
+			// Decide whether this was a rights failure, or an identification failure.
168
+
169
+			if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
+				// Not identified
171
+				throw new NotIdentifiedException($this->getSecurityManager());
172
+			}
173
+			elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
+				// Nope, plain old access denied
175
+				throw new AccessDeniedException($this->getSecurityManager());
176
+			}
177
+			else {
178
+				throw new Exception('Unknown response from security manager.');
179
+			}
180
+		}
181
+	}
182
+
183
+	/**
184
+	 * Tests the security barrier for a specified action.
185
+	 *
186
+	 * Don't use within templates
187
+	 *
188
+	 * @param string      $action
189
+	 *
190
+	 * @param User        $user
191
+	 * @param null|string $pageName
192
+	 *
193
+	 * @return bool
194
+	 * @category Security-Critical
195
+	 */
196
+	final public function barrierTest($action, User $user, $pageName = null)
197
+	{
198
+		$page = get_called_class();
199
+		if ($pageName !== null) {
200
+			$page = $pageName;
201
+		}
202
+
203
+		$securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
+
205
+		return $securityResult === SecurityManager::ALLOWED;
206
+	}
207
+
208
+	/**
209
+	 * Updates the lastactive timestamp
210
+	 */
211
+	private function touchUserLastActive()
212
+	{
213
+		if (WebRequest::getSessionUserId() !== null) {
214
+			$query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
+			$this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
+		}
217
+	}
218
+
219
+	/**
220
+	 * @return SecurityManager
221
+	 */
222
+	public function getSecurityManager()
223
+	{
224
+		return $this->securityManager;
225
+	}
226
+
227
+	/**
228
+	 * @param SecurityManager $securityManager
229
+	 */
230
+	public function setSecurityManager(SecurityManager $securityManager)
231
+	{
232
+		$this->securityManager = $securityManager;
233
+	}
234
+
235
+	/**
236
+	 * @return IBlacklistHelper
237
+	 */
238
+	public function getBlacklistHelper()
239
+	{
240
+		return $this->blacklistHelper;
241
+	}
242
+
243
+	/**
244
+	 * @param IBlacklistHelper $blacklistHelper
245
+	 */
246
+	public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
+	{
248
+		$this->blacklistHelper = $blacklistHelper;
249
+	}
250 250
 }
Please login to merge, or discard this patch.
includes/ConsoleTasks/RunJobQueueTask.php 3 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
                 // Create a task.
79 79
                 $taskName = $job->getTask();
80 80
 
81
-                if(!class_exists($taskName)) {
81
+                if (!class_exists($taskName)) {
82 82
                     throw new ApplicationLogicException('Job task does not exist');
83 83
                 }
84 84
 
@@ -132,6 +132,6 @@  discard block
 block discarded – undo
132 132
     }
133 133
 
134 134
     public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
135
+        throw new Exception($errfile."@".$errline.": ".$errstr);
136 136
     }
137 137
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -131,7 +131,8 @@
 block discarded – undo
131 131
         $task->setNotificationHelper($this->getNotificationHelper());
132 132
     }
133 133
 
134
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
134
+    public static function errorHandler($errno, $errstr, $errfile, $errline)
135
+    {
135 136
         throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136 137
     }
137 138
 }
Please login to merge, or discard this patch.
Indentation   +114 added lines, -114 removed lines patch added patch discarded remove patch
@@ -21,118 +21,118 @@
 block discarded – undo
21 21
 
22 22
 class RunJobQueueTask extends ConsoleTaskBase
23 23
 {
24
-    private $taskList = array(
25
-        WelcomeUserTask::class,
26
-        BotCreationTask::class,
27
-        UserCreationTask::class
28
-    );
29
-
30
-    public function execute()
31
-    {
32
-        $database = $this->getDatabase();
33
-
34
-        // ensure we're running inside a tx here.
35
-        if (!$database->hasActiveTransaction()) {
36
-            $database->beginTransaction();
37
-        }
38
-
39
-        $sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
40
-        $statement = $database->prepare($sql);
41
-        $statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
42
-        /** @var JobQueue[] $queuedJobs */
43
-        $queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
44
-
45
-        // mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
46
-        // We'll re-lock the row when we get to it.
47
-        foreach ($queuedJobs as $job) {
48
-            $job->setDatabase($database);
49
-            $job->setStatus(JobQueue::STATUS_WAITING);
50
-            $job->setError(null);
51
-            $job->setAcknowledged(null);
52
-            $job->save();
53
-        }
54
-
55
-        $database->commit();
56
-
57
-        set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
58
-
59
-        foreach ($queuedJobs as $job) {
60
-            try {
61
-                // refresh from the database
62
-                /** @var JobQueue $job */
63
-                $job = JobQueue::getById($job->getId(), $database);
64
-
65
-                if ($job->getStatus() !== JobQueue::STATUS_WAITING) {
66
-                    continue;
67
-                }
68
-
69
-                $database->beginTransaction();
70
-                $job->setStatus(JobQueue::STATUS_RUNNING);
71
-                $job->save();
72
-                $database->commit();
73
-
74
-                $database->beginTransaction();
75
-
76
-                // re-lock the job
77
-                $job->setStatus(JobQueue::STATUS_RUNNING);
78
-                $job->save();
79
-
80
-                // validate we're allowed to run the requested task (whitelist)
81
-                if (!in_array($job->getTask(), $this->taskList)) {
82
-                    throw new ApplicationLogicException('Job task not registered');
83
-                }
84
-
85
-                // Create a task.
86
-                $taskName = $job->getTask();
87
-
88
-                if(!class_exists($taskName)) {
89
-                    throw new ApplicationLogicException('Job task does not exist');
90
-                }
91
-
92
-                /** @var BackgroundTaskBase $task */
93
-                $task = new $taskName;
94
-
95
-                $this->setupTask($task, $job);
96
-                $task->run();
97
-            }
98
-            catch (Exception $ex) {
99
-                $database->rollBack();
100
-                $database->beginTransaction();
101
-
102
-                /** @var JobQueue $job */
103
-                $job = JobQueue::getById($job->getId(), $database);
104
-                $job->setDatabase($database);
105
-                $job->setStatus(JobQueue::STATUS_FAILED);
106
-                $job->setError($ex->getMessage());
107
-                $job->setAcknowledged(0);
108
-                $job->save();
109
-
110
-                Logger::backgroundJobIssue($this->getDatabase(), $job);
111
-
112
-                $database->commit();
113
-            }
114
-            finally {
115
-                $database->commit();
116
-            }
117
-        }
118
-    }
119
-
120
-    /**
121
-     * @param BackgroundTaskBase $task
122
-     * @param JobQueue           $job
123
-     */
124
-    private function setupTask(BackgroundTaskBase $task, JobQueue $job)
125
-    {
126
-        $task->setJob($job);
127
-        $task->setDatabase($this->getDatabase());
128
-        $task->setHttpHelper($this->getHttpHelper());
129
-        $task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
130
-        $task->setEmailHelper($this->getEmailHelper());
131
-        $task->setSiteConfiguration($this->getSiteConfiguration());
132
-        $task->setNotificationHelper($this->getNotificationHelper());
133
-    }
134
-
135
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
136
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
137
-    }
24
+	private $taskList = array(
25
+		WelcomeUserTask::class,
26
+		BotCreationTask::class,
27
+		UserCreationTask::class
28
+	);
29
+
30
+	public function execute()
31
+	{
32
+		$database = $this->getDatabase();
33
+
34
+		// ensure we're running inside a tx here.
35
+		if (!$database->hasActiveTransaction()) {
36
+			$database->beginTransaction();
37
+		}
38
+
39
+		$sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
40
+		$statement = $database->prepare($sql);
41
+		$statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
42
+		/** @var JobQueue[] $queuedJobs */
43
+		$queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
44
+
45
+		// mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
46
+		// We'll re-lock the row when we get to it.
47
+		foreach ($queuedJobs as $job) {
48
+			$job->setDatabase($database);
49
+			$job->setStatus(JobQueue::STATUS_WAITING);
50
+			$job->setError(null);
51
+			$job->setAcknowledged(null);
52
+			$job->save();
53
+		}
54
+
55
+		$database->commit();
56
+
57
+		set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
58
+
59
+		foreach ($queuedJobs as $job) {
60
+			try {
61
+				// refresh from the database
62
+				/** @var JobQueue $job */
63
+				$job = JobQueue::getById($job->getId(), $database);
64
+
65
+				if ($job->getStatus() !== JobQueue::STATUS_WAITING) {
66
+					continue;
67
+				}
68
+
69
+				$database->beginTransaction();
70
+				$job->setStatus(JobQueue::STATUS_RUNNING);
71
+				$job->save();
72
+				$database->commit();
73
+
74
+				$database->beginTransaction();
75
+
76
+				// re-lock the job
77
+				$job->setStatus(JobQueue::STATUS_RUNNING);
78
+				$job->save();
79
+
80
+				// validate we're allowed to run the requested task (whitelist)
81
+				if (!in_array($job->getTask(), $this->taskList)) {
82
+					throw new ApplicationLogicException('Job task not registered');
83
+				}
84
+
85
+				// Create a task.
86
+				$taskName = $job->getTask();
87
+
88
+				if(!class_exists($taskName)) {
89
+					throw new ApplicationLogicException('Job task does not exist');
90
+				}
91
+
92
+				/** @var BackgroundTaskBase $task */
93
+				$task = new $taskName;
94
+
95
+				$this->setupTask($task, $job);
96
+				$task->run();
97
+			}
98
+			catch (Exception $ex) {
99
+				$database->rollBack();
100
+				$database->beginTransaction();
101
+
102
+				/** @var JobQueue $job */
103
+				$job = JobQueue::getById($job->getId(), $database);
104
+				$job->setDatabase($database);
105
+				$job->setStatus(JobQueue::STATUS_FAILED);
106
+				$job->setError($ex->getMessage());
107
+				$job->setAcknowledged(0);
108
+				$job->save();
109
+
110
+				Logger::backgroundJobIssue($this->getDatabase(), $job);
111
+
112
+				$database->commit();
113
+			}
114
+			finally {
115
+				$database->commit();
116
+			}
117
+		}
118
+	}
119
+
120
+	/**
121
+	 * @param BackgroundTaskBase $task
122
+	 * @param JobQueue           $job
123
+	 */
124
+	private function setupTask(BackgroundTaskBase $task, JobQueue $job)
125
+	{
126
+		$task->setJob($job);
127
+		$task->setDatabase($this->getDatabase());
128
+		$task->setHttpHelper($this->getHttpHelper());
129
+		$task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
130
+		$task->setEmailHelper($this->getEmailHelper());
131
+		$task->setSiteConfiguration($this->getSiteConfiguration());
132
+		$task->setNotificationHelper($this->getNotificationHelper());
133
+	}
134
+
135
+	public static function errorHandler($errno, $errstr, $errfile, $errline) {
136
+		throw new Exception($errfile . "@" . $errline . ": " . $errstr);
137
+	}
138 138
 }
Please login to merge, or discard this patch.
includes/API/Actions/JsTemplateConfirmsAction.php 2 patches
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -17,20 +17,20 @@
 block discarded – undo
17 17
 
18 18
 class JsTemplateConfirmsAction extends JsonApiPageBase implements IJsonApiAction
19 19
 {
20
-    public function executeApiAction()
21
-    {
22
-        $this->getDatabase();
20
+	public function executeApiAction()
21
+	{
22
+		$this->getDatabase();
23 23
 
24
-        /** @var EmailTemplate[] $templates */
25
-        $templates = EmailTemplate::getAllActiveTemplates(null, $this->getDatabase());
24
+		/** @var EmailTemplate[] $templates */
25
+		$templates = EmailTemplate::getAllActiveTemplates(null, $this->getDatabase());
26 26
 
27
-        $dataset = [];
28
-        foreach ($templates as $tpl) {
29
-            if($tpl->getJsquestion() != "") {
30
-                $dataset[$tpl->getId()] = $tpl->getJsquestion();
31
-            }
32
-        }
27
+		$dataset = [];
28
+		foreach ($templates as $tpl) {
29
+			if($tpl->getJsquestion() != "") {
30
+				$dataset[$tpl->getId()] = $tpl->getJsquestion();
31
+			}
32
+		}
33 33
 
34
-        return $dataset;
35
-    }
34
+		return $dataset;
35
+	}
36 36
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@
 block discarded – undo
26 26
 
27 27
         $dataset = [];
28 28
         foreach ($templates as $tpl) {
29
-            if($tpl->getJsquestion() != "") {
29
+            if ($tpl->getJsquestion() != "") {
30 30
                 $dataset[$tpl->getId()] = $tpl->getJsquestion();
31 31
             }
32 32
         }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PagePreferences.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -16,94 +16,94 @@
 block discarded – undo
16 16
 
17 17
 class PagePreferences extends InternalPageBase
18 18
 {
19
-    /**
20
-     * Main function for this page, when no specific actions are called.
21
-     * @return void
22
-     */
23
-    protected function main()
24
-    {
25
-        $this->setHtmlTitle('Preferences');
26
-
27
-        $enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
-        $database = $this->getDatabase();
29
-        $user = User::getCurrent($database);
30
-
31
-        // Dual mode
32
-        if (WebRequest::wasPosted()) {
33
-            $this->validateCSRFToken();
34
-            $user->setWelcomeSig(WebRequest::postString('sig'));
35
-            $user->setEmailSig(WebRequest::postString('emailsig'));
36
-            $user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
-            $this->setCreationMode($user);
38
-            $user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
-
40
-            $email = WebRequest::postEmail('email');
41
-            if ($email !== null) {
42
-                $user->setEmail($email);
43
-            }
44
-
45
-            $user->save();
46
-            SessionAlert::success("Preferences updated!");
47
-
48
-            $this->redirect('');
49
-        }
50
-        else {
51
-            $this->assignCSRFToken();
52
-            $this->setTemplate('preferences/prefs.tpl');
53
-            $this->assign("enforceOAuth", $enforceOAuth);
54
-
55
-            $this->assign('canManualCreate',
56
-                $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
-            $this->assign('canOauthCreate',
58
-                $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
-            $this->assign('canBotCreate',
60
-                $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
-
62
-            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
-                $this->getSiteConfiguration());
64
-            $this->assign('oauth', $oauth);
65
-
66
-            $identity = null;
67
-            if ($oauth->isFullyLinked()) {
68
-                $identity = $oauth->getIdentity();
69
-            }
70
-
71
-            $this->assign('identity', $identity);
72
-            $this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
-        }
74
-    }
75
-
76
-    protected function refreshOAuth()
77
-    {
78
-        if (!WebRequest::wasPosted()) {
79
-            $this->redirect('preferences');
80
-
81
-            return;
82
-        }
83
-
84
-        $database = $this->getDatabase();
85
-        $oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
-            $this->getSiteConfiguration());
87
-        if ($oauth->isFullyLinked()) {
88
-            $oauth->refreshIdentity();
89
-        }
90
-
91
-        $this->redirect('preferences');
92
-
93
-        return;
94
-    }
95
-
96
-    /**
97
-     * @param User $user
98
-     */
99
-    protected function setCreationMode(User $user)
100
-    {
101
-        // if the user is selecting a creation mode that they are not allowed, do nothing.
102
-        // this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
-        // or that they have kept from when they previously had certain access.
104
-        $creationMode = WebRequest::postInt('creationmode');
105
-        if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
-            $user->setCreationMode($creationMode);
107
-        }
108
-    }
19
+	/**
20
+	 * Main function for this page, when no specific actions are called.
21
+	 * @return void
22
+	 */
23
+	protected function main()
24
+	{
25
+		$this->setHtmlTitle('Preferences');
26
+
27
+		$enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
+		$database = $this->getDatabase();
29
+		$user = User::getCurrent($database);
30
+
31
+		// Dual mode
32
+		if (WebRequest::wasPosted()) {
33
+			$this->validateCSRFToken();
34
+			$user->setWelcomeSig(WebRequest::postString('sig'));
35
+			$user->setEmailSig(WebRequest::postString('emailsig'));
36
+			$user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
+			$this->setCreationMode($user);
38
+			$user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
+
40
+			$email = WebRequest::postEmail('email');
41
+			if ($email !== null) {
42
+				$user->setEmail($email);
43
+			}
44
+
45
+			$user->save();
46
+			SessionAlert::success("Preferences updated!");
47
+
48
+			$this->redirect('');
49
+		}
50
+		else {
51
+			$this->assignCSRFToken();
52
+			$this->setTemplate('preferences/prefs.tpl');
53
+			$this->assign("enforceOAuth", $enforceOAuth);
54
+
55
+			$this->assign('canManualCreate',
56
+				$this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
+			$this->assign('canOauthCreate',
58
+				$this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
+			$this->assign('canBotCreate',
60
+				$this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
+
62
+			$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
+				$this->getSiteConfiguration());
64
+			$this->assign('oauth', $oauth);
65
+
66
+			$identity = null;
67
+			if ($oauth->isFullyLinked()) {
68
+				$identity = $oauth->getIdentity();
69
+			}
70
+
71
+			$this->assign('identity', $identity);
72
+			$this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
+		}
74
+	}
75
+
76
+	protected function refreshOAuth()
77
+	{
78
+		if (!WebRequest::wasPosted()) {
79
+			$this->redirect('preferences');
80
+
81
+			return;
82
+		}
83
+
84
+		$database = $this->getDatabase();
85
+		$oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
+			$this->getSiteConfiguration());
87
+		if ($oauth->isFullyLinked()) {
88
+			$oauth->refreshIdentity();
89
+		}
90
+
91
+		$this->redirect('preferences');
92
+
93
+		return;
94
+	}
95
+
96
+	/**
97
+	 * @param User $user
98
+	 */
99
+	protected function setCreationMode(User $user)
100
+	{
101
+		// if the user is selecting a creation mode that they are not allowed, do nothing.
102
+		// this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
+		// or that they have kept from when they previously had certain access.
104
+		$creationMode = WebRequest::postInt('creationmode');
105
+		if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
+			$user->setCreationMode($creationMode);
107
+		}
108
+	}
109 109
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCustomClose.php 1 patch
Indentation   +274 added lines, -274 removed lines patch added patch discarded remove patch
@@ -24,278 +24,278 @@
 block discarded – undo
24 24
 
25 25
 class PageCustomClose extends PageCloseRequest
26 26
 {
27
-    use RequestData;
28
-
29
-    protected function main()
30
-    {
31
-        $database = $this->getDatabase();
32
-
33
-        $request = $this->getRequest($database);
34
-        $currentUser = User::getCurrent($this->getDatabase());
35
-
36
-        if ($request->getStatus() === 'Closed') {
37
-            throw new ApplicationLogicException('Request is already closed');
38
-        }
39
-
40
-        // Dual-mode page
41
-        if (WebRequest::wasPosted()) {
42
-            $this->validateCSRFToken();
43
-            $this->doCustomClose($currentUser, $request, $database);
44
-
45
-            $this->redirect();
46
-        }
47
-        else {
48
-            $this->assignCSRFToken();
49
-            $this->showCustomCloseForm($database, $request);
50
-        }
51
-    }
52
-
53
-    /**
54
-     * @param $database
55
-     *
56
-     * @return Request
57
-     * @throws ApplicationLogicException
58
-     */
59
-    protected function getRequest(PdoDatabase $database)
60
-    {
61
-        $requestId = WebRequest::getInt('request');
62
-        if ($requestId === null) {
63
-            throw new ApplicationLogicException('Request ID not found');
64
-        }
65
-
66
-        /** @var Request $request */
67
-        $request = Request::getById($requestId, $database);
68
-
69
-        if ($request === false) {
70
-            throw new ApplicationLogicException('Request not found');
71
-        }
72
-
73
-        return $request;
74
-    }
75
-
76
-    /**
77
-     * @param PdoDatabase $database
78
-     *
79
-     * @return EmailTemplate|null
80
-     */
81
-    protected function getTemplate(PdoDatabase $database)
82
-    {
83
-        $templateId = WebRequest::getInt('template');
84
-        if ($templateId === null) {
85
-            return null;
86
-        }
87
-
88
-        /** @var EmailTemplate $template */
89
-        $template = EmailTemplate::getById($templateId, $database);
90
-        if ($template === false || !$template->getActive()) {
91
-            return null;
92
-        }
93
-
94
-        return $template;
95
-    }
96
-
97
-    /**
98
-     * @param $database
99
-     * @param $request
100
-     *
101
-     * @throws Exception
102
-     */
103
-    protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
-    {
105
-        $currentUser = User::getCurrent($database);
106
-        $config = $this->getSiteConfiguration();
107
-
108
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
-        if (!$allowedPrivateData) {
110
-            // we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
-            throw new AccessDeniedException($this->getSecurityManager());
112
-        }
113
-
114
-        $template = $this->getTemplate($database);
115
-
116
-        // Preload data
117
-        $this->assign('defaultAction', '');
118
-        $this->assign('preloadText', '');
119
-        $this->assign('preloadTitle', '');
120
-
121
-        if ($template !== null) {
122
-            $this->assign('defaultAction', $template->getDefaultAction());
123
-            $this->assign('preloadText', $template->getText());
124
-            $this->assign('preloadTitle', $template->getName());
125
-        }
126
-
127
-        // Static data
128
-        $this->assign('requeststates', $config->getRequestStates());
129
-
130
-        // request data
131
-        $this->assign('requestId', $request->getIp());
132
-        $this->assign('updateVersion', $request->getUpdateVersion());
133
-        $this->setupBasicData($request, $config);
134
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
-        $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
-
137
-        // IP location
138
-        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
-        $this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
-
141
-        // Confirmations
142
-        $this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
-
144
-        $this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
-
146
-        $this->assign('allowWelcomeSkip', false);
147
-        $this->assign('forceWelcomeSkip', false);
148
-
149
-        $oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
-
151
-        if ($currentUser->getWelcomeTemplate() != 0) {
152
-            $this->assign('allowWelcomeSkip', true);
153
-
154
-            if (!$oauth->canWelcome()) {
155
-                $this->assign('forceWelcomeSkip', true);
156
-            }
157
-        }
158
-
159
-
160
-        // template
161
-        $this->setTemplate('custom-close.tpl');
162
-    }
163
-
164
-    /**
165
-     * @param User        $currentUser
166
-     * @param Request     $request
167
-     * @param PdoDatabase $database
168
-     *
169
-     * @throws ApplicationLogicException
170
-     */
171
-    protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
-    {
173
-        $messageBody = WebRequest::postString('msgbody');
174
-        if ($messageBody === null || trim($messageBody) === '') {
175
-            throw new ApplicationLogicException('Message body cannot be blank');
176
-        }
177
-
178
-        $ccMailingList = true;
179
-        if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
-            $ccMailingList = WebRequest::postBoolean('ccMailingList');
181
-        }
182
-
183
-        if ($request->getStatus() === 'Closed') {
184
-            throw new ApplicationLogicException('Request is already closed');
185
-        }
186
-
187
-        if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
-        ) {
189
-            throw new ApplicationLogicException('Not all confirmations checked');
190
-        }
191
-
192
-        $action = WebRequest::postString('action');
193
-        $availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
-
195
-        if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
-            // Close request
197
-            $this->closeRequest($request, $database, $action, $messageBody);
198
-
199
-            $this->processWelcome($action);
200
-
201
-            // Send the mail after the save, since save can be rolled back
202
-            $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
-        }
204
-        else {
205
-            if (array_key_exists($action, $availableRequestStates)) {
206
-                // Defer to other state
207
-                $this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
-
209
-                // Send the mail after the save, since save can be rolled back
210
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
-            }
212
-            else {
213
-                $request->setReserved(null);
214
-                $request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
-                $request->save();
216
-
217
-                // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
-                // and be rolled back.
219
-
220
-                // Send mail
221
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
-
223
-                Logger::sentMail($database, $request, $messageBody);
224
-                Logger::unreserve($database, $request);
225
-
226
-                $this->getNotificationHelper()->sentMail($request);
227
-                SessionAlert::success("Sent mail to Request {$request->getId()}");
228
-            }
229
-        }
230
-    }
231
-
232
-    /**
233
-     * @param Request     $request
234
-     * @param PdoDatabase $database
235
-     * @param string      $action
236
-     * @param string      $messageBody
237
-     *
238
-     * @throws Exception
239
-     * @throws OptimisticLockFailedException
240
-     */
241
-    protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
-    {
243
-        $request->setStatus('Closed');
244
-        $request->setReserved(null);
245
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
-        $request->save();
247
-
248
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
-        // be rolled back.
250
-
251
-        if ($action == EmailTemplate::CREATED) {
252
-            $logCloseType = 'custom-y';
253
-            $notificationCloseType = "Custom, Created";
254
-        }
255
-        else {
256
-            $logCloseType = 'custom-n';
257
-            $notificationCloseType = "Custom, Not Created";
258
-        }
259
-
260
-        Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
-        $this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
-
263
-        $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
-        SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
-    }
266
-
267
-    /**
268
-     * @param Request     $request
269
-     * @param PdoDatabase $database
270
-     * @param string      $action
271
-     * @param             $availableRequestStates
272
-     * @param string      $messageBody
273
-     *
274
-     * @throws Exception
275
-     * @throws OptimisticLockFailedException
276
-     */
277
-    protected function deferRequest(
278
-        Request $request,
279
-        PdoDatabase $database,
280
-        $action,
281
-        $availableRequestStates,
282
-        $messageBody
283
-    ) {
284
-        $request->setStatus($action);
285
-        $request->setReserved(null);
286
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
-        $request->save();
288
-
289
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
-        // and be rolled back.
291
-
292
-        $deferToLog = $availableRequestStates[$action]['defertolog'];
293
-        Logger::sentMail($database, $request, $messageBody);
294
-        Logger::deferRequest($database, $request, $deferToLog);
295
-
296
-        $this->getNotificationHelper()->requestDeferredWithMail($request);
297
-
298
-        $deferTo = $availableRequestStates[$action]['deferto'];
299
-        SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
-    }
27
+	use RequestData;
28
+
29
+	protected function main()
30
+	{
31
+		$database = $this->getDatabase();
32
+
33
+		$request = $this->getRequest($database);
34
+		$currentUser = User::getCurrent($this->getDatabase());
35
+
36
+		if ($request->getStatus() === 'Closed') {
37
+			throw new ApplicationLogicException('Request is already closed');
38
+		}
39
+
40
+		// Dual-mode page
41
+		if (WebRequest::wasPosted()) {
42
+			$this->validateCSRFToken();
43
+			$this->doCustomClose($currentUser, $request, $database);
44
+
45
+			$this->redirect();
46
+		}
47
+		else {
48
+			$this->assignCSRFToken();
49
+			$this->showCustomCloseForm($database, $request);
50
+		}
51
+	}
52
+
53
+	/**
54
+	 * @param $database
55
+	 *
56
+	 * @return Request
57
+	 * @throws ApplicationLogicException
58
+	 */
59
+	protected function getRequest(PdoDatabase $database)
60
+	{
61
+		$requestId = WebRequest::getInt('request');
62
+		if ($requestId === null) {
63
+			throw new ApplicationLogicException('Request ID not found');
64
+		}
65
+
66
+		/** @var Request $request */
67
+		$request = Request::getById($requestId, $database);
68
+
69
+		if ($request === false) {
70
+			throw new ApplicationLogicException('Request not found');
71
+		}
72
+
73
+		return $request;
74
+	}
75
+
76
+	/**
77
+	 * @param PdoDatabase $database
78
+	 *
79
+	 * @return EmailTemplate|null
80
+	 */
81
+	protected function getTemplate(PdoDatabase $database)
82
+	{
83
+		$templateId = WebRequest::getInt('template');
84
+		if ($templateId === null) {
85
+			return null;
86
+		}
87
+
88
+		/** @var EmailTemplate $template */
89
+		$template = EmailTemplate::getById($templateId, $database);
90
+		if ($template === false || !$template->getActive()) {
91
+			return null;
92
+		}
93
+
94
+		return $template;
95
+	}
96
+
97
+	/**
98
+	 * @param $database
99
+	 * @param $request
100
+	 *
101
+	 * @throws Exception
102
+	 */
103
+	protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
+	{
105
+		$currentUser = User::getCurrent($database);
106
+		$config = $this->getSiteConfiguration();
107
+
108
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
+		if (!$allowedPrivateData) {
110
+			// we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
+			throw new AccessDeniedException($this->getSecurityManager());
112
+		}
113
+
114
+		$template = $this->getTemplate($database);
115
+
116
+		// Preload data
117
+		$this->assign('defaultAction', '');
118
+		$this->assign('preloadText', '');
119
+		$this->assign('preloadTitle', '');
120
+
121
+		if ($template !== null) {
122
+			$this->assign('defaultAction', $template->getDefaultAction());
123
+			$this->assign('preloadText', $template->getText());
124
+			$this->assign('preloadTitle', $template->getName());
125
+		}
126
+
127
+		// Static data
128
+		$this->assign('requeststates', $config->getRequestStates());
129
+
130
+		// request data
131
+		$this->assign('requestId', $request->getIp());
132
+		$this->assign('updateVersion', $request->getUpdateVersion());
133
+		$this->setupBasicData($request, $config);
134
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
+		$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
+
137
+		// IP location
138
+		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
+		$this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
+
141
+		// Confirmations
142
+		$this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
+
144
+		$this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
+
146
+		$this->assign('allowWelcomeSkip', false);
147
+		$this->assign('forceWelcomeSkip', false);
148
+
149
+		$oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
+
151
+		if ($currentUser->getWelcomeTemplate() != 0) {
152
+			$this->assign('allowWelcomeSkip', true);
153
+
154
+			if (!$oauth->canWelcome()) {
155
+				$this->assign('forceWelcomeSkip', true);
156
+			}
157
+		}
158
+
159
+
160
+		// template
161
+		$this->setTemplate('custom-close.tpl');
162
+	}
163
+
164
+	/**
165
+	 * @param User        $currentUser
166
+	 * @param Request     $request
167
+	 * @param PdoDatabase $database
168
+	 *
169
+	 * @throws ApplicationLogicException
170
+	 */
171
+	protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
+	{
173
+		$messageBody = WebRequest::postString('msgbody');
174
+		if ($messageBody === null || trim($messageBody) === '') {
175
+			throw new ApplicationLogicException('Message body cannot be blank');
176
+		}
177
+
178
+		$ccMailingList = true;
179
+		if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
+			$ccMailingList = WebRequest::postBoolean('ccMailingList');
181
+		}
182
+
183
+		if ($request->getStatus() === 'Closed') {
184
+			throw new ApplicationLogicException('Request is already closed');
185
+		}
186
+
187
+		if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
+		) {
189
+			throw new ApplicationLogicException('Not all confirmations checked');
190
+		}
191
+
192
+		$action = WebRequest::postString('action');
193
+		$availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
+
195
+		if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
+			// Close request
197
+			$this->closeRequest($request, $database, $action, $messageBody);
198
+
199
+			$this->processWelcome($action);
200
+
201
+			// Send the mail after the save, since save can be rolled back
202
+			$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
+		}
204
+		else {
205
+			if (array_key_exists($action, $availableRequestStates)) {
206
+				// Defer to other state
207
+				$this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
+
209
+				// Send the mail after the save, since save can be rolled back
210
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
+			}
212
+			else {
213
+				$request->setReserved(null);
214
+				$request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
+				$request->save();
216
+
217
+				// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
+				// and be rolled back.
219
+
220
+				// Send mail
221
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
+
223
+				Logger::sentMail($database, $request, $messageBody);
224
+				Logger::unreserve($database, $request);
225
+
226
+				$this->getNotificationHelper()->sentMail($request);
227
+				SessionAlert::success("Sent mail to Request {$request->getId()}");
228
+			}
229
+		}
230
+	}
231
+
232
+	/**
233
+	 * @param Request     $request
234
+	 * @param PdoDatabase $database
235
+	 * @param string      $action
236
+	 * @param string      $messageBody
237
+	 *
238
+	 * @throws Exception
239
+	 * @throws OptimisticLockFailedException
240
+	 */
241
+	protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
+	{
243
+		$request->setStatus('Closed');
244
+		$request->setReserved(null);
245
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
+		$request->save();
247
+
248
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
+		// be rolled back.
250
+
251
+		if ($action == EmailTemplate::CREATED) {
252
+			$logCloseType = 'custom-y';
253
+			$notificationCloseType = "Custom, Created";
254
+		}
255
+		else {
256
+			$logCloseType = 'custom-n';
257
+			$notificationCloseType = "Custom, Not Created";
258
+		}
259
+
260
+		Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
+		$this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
+
263
+		$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
+		SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
+	}
266
+
267
+	/**
268
+	 * @param Request     $request
269
+	 * @param PdoDatabase $database
270
+	 * @param string      $action
271
+	 * @param             $availableRequestStates
272
+	 * @param string      $messageBody
273
+	 *
274
+	 * @throws Exception
275
+	 * @throws OptimisticLockFailedException
276
+	 */
277
+	protected function deferRequest(
278
+		Request $request,
279
+		PdoDatabase $database,
280
+		$action,
281
+		$availableRequestStates,
282
+		$messageBody
283
+	) {
284
+		$request->setStatus($action);
285
+		$request->setReserved(null);
286
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
+		$request->save();
288
+
289
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
+		// and be rolled back.
291
+
292
+		$deferToLog = $availableRequestStates[$action]['defertolog'];
293
+		Logger::sentMail($database, $request, $messageBody);
294
+		Logger::deferRequest($database, $request, $deferToLog);
295
+
296
+		$this->getNotificationHelper()->requestDeferredWithMail($request);
297
+
298
+		$deferTo = $availableRequestStates[$action]['deferto'];
299
+		SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
+	}
301 301
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCloseRequest.php 2 patches
Indentation   +225 added lines, -225 removed lines patch added patch discarded remove patch
@@ -21,229 +21,229 @@
 block discarded – undo
21 21
 
22 22
 class PageCloseRequest extends RequestActionBase
23 23
 {
24
-    protected function main()
25
-    {
26
-        $this->processClose();
27
-    }
28
-
29
-    /**
30
-     * Main function for this page, when no specific actions are called.
31
-     * @throws ApplicationLogicException
32
-     */
33
-    final protected function processClose()
34
-    {
35
-        $this->checkPosted();
36
-        $database = $this->getDatabase();
37
-
38
-        $currentUser = User::getCurrent($database);
39
-        $template = $this->getTemplate($database);
40
-        $request = $this->getRequest($database);
41
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
-
43
-        if ($request->getStatus() === 'Closed') {
44
-            throw new ApplicationLogicException('Request is already closed');
45
-        }
46
-
47
-        if ($this->confirmEmailAlreadySent($request, $template)) {
48
-            return;
49
-        }
50
-
51
-        if ($this->checkReserveProtect($request, $currentUser)) {
52
-            return;
53
-        }
54
-
55
-        if ($this->confirmAccountCreated($request, $template)) {
56
-            return;
57
-        }
58
-
59
-        // I think we're good here...
60
-        $request->setStatus('Closed');
61
-        $request->setReserved(null);
62
-
63
-        Logger::closeRequest($database, $request, $template->getId(), null);
64
-
65
-        $request->save();
66
-
67
-        $this->processWelcome($template->getDefaultAction());
68
-
69
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
-        // be rolled back.
71
-
72
-        $this->getNotificationHelper()->requestClosed($request, $template->getName());
73
-        $sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
-        SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
-
76
-        $this->sendMail($request, $template->getText(), $currentUser, false);
77
-
78
-        $this->redirect();
79
-    }
80
-
81
-    /**
82
-     * @param PdoDatabase $database
83
-     *
84
-     * @return EmailTemplate
85
-     * @throws ApplicationLogicException
86
-     */
87
-    protected function getTemplate(PdoDatabase $database)
88
-    {
89
-        $templateId = WebRequest::postInt('template');
90
-        if ($templateId === null) {
91
-            throw new ApplicationLogicException('No template specified');
92
-        }
93
-
94
-        /** @var EmailTemplate $template */
95
-        $template = EmailTemplate::getById($templateId, $database);
96
-        if ($template === false || !$template->getActive()) {
97
-            throw new ApplicationLogicException('Invalid or inactive template specified');
98
-        }
99
-
100
-        return $template;
101
-    }
102
-
103
-    /**
104
-     * @param Request       $request
105
-     * @param EmailTemplate $template
106
-     *
107
-     * @return bool
108
-     */
109
-    protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
-    {
111
-        if ($this->checkEmailAlreadySent($request)) {
112
-            $this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
-
114
-            return true;
115
-        }
116
-
117
-        return false;
118
-    }
119
-
120
-    protected function checkEmailAlreadySent(Request $request)
121
-    {
122
-        if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
-            return true;
124
-        }
125
-
126
-        return false;
127
-    }
128
-
129
-    protected function checkReserveProtect(Request $request, User $currentUser)
130
-    {
131
-        $reservationId = $request->getReserved();
132
-
133
-        if ($reservationId !== 0 && $reservationId !== null) {
134
-            if ($currentUser->getId() !== $reservationId) {
135
-                SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
-                return true;
138
-            }
139
-        }
140
-
141
-        return false;
142
-    }
143
-
144
-    /**
145
-     * @param Request       $request
146
-     * @param EmailTemplate $template
147
-     *
148
-     * @return bool
149
-     * @throws \Waca\Exceptions\CurlException
150
-     */
151
-    protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
-    {
153
-        if ($this->checkAccountCreated($request, $template)) {
154
-            $this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
-
156
-            return true;
157
-        }
158
-
159
-        return false;
160
-    }
161
-
162
-    protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
-    {
164
-        if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
-            $parameters = array(
166
-                'action'  => 'query',
167
-                'list'    => 'users',
168
-                'format'  => 'php',
169
-                'ususers' => $request->getName(),
170
-            );
171
-
172
-            $content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
-                $parameters);
174
-
175
-            $apiResult = unserialize($content);
176
-            $exists = !isset($apiResult['query']['users']['0']['missing']);
177
-
178
-            if (!$exists) {
179
-                return true;
180
-            }
181
-        }
182
-
183
-        return false;
184
-    }
185
-
186
-    /**
187
-     * @param Request $request
188
-     * @param string  $mailText
189
-     * @param User    $currentUser
190
-     * @param boolean $ccMailingList
191
-     */
192
-    protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
-    {
194
-        $requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
-        $requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
-
197
-        $request->setEmailSent(true);
198
-        $request->save();
199
-    }
200
-
201
-    /**
202
-     * @param Request       $request
203
-     * @param EmailTemplate $template
204
-     * @param string        $templateName
205
-     *
206
-     * @throws Exception
207
-     * @return void
208
-     */
209
-    protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
-    {
211
-        $this->assignCSRFToken();
212
-
213
-        $this->assign('request', $request->getId());
214
-        $this->assign('template', $template->getId());
215
-
216
-        $this->assign('updateversion', $request->getUpdateVersion());
217
-
218
-        $this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
-        $this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
-        $this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
-
222
-        $this->setTemplate($templateName);
223
-    }
224
-
225
-    /**
226
-     * @param string $action
227
-     *
228
-     * @throws ApplicationLogicException
229
-     */
230
-    final protected function processWelcome(string $action): void
231
-    {
232
-        $database = $this->getDatabase();
233
-        $currentUser = User::getCurrent($database);
234
-
235
-        if ($action !== EmailTemplate::CREATED) {
236
-            return;
237
-        }
238
-
239
-        if ($currentUser->getWelcomeTemplate() === null) {
240
-            return;
241
-        }
242
-
243
-        if (WebRequest::postBoolean('skipAutoWelcome')) {
244
-            return;
245
-        }
246
-
247
-        $this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
-    }
24
+	protected function main()
25
+	{
26
+		$this->processClose();
27
+	}
28
+
29
+	/**
30
+	 * Main function for this page, when no specific actions are called.
31
+	 * @throws ApplicationLogicException
32
+	 */
33
+	final protected function processClose()
34
+	{
35
+		$this->checkPosted();
36
+		$database = $this->getDatabase();
37
+
38
+		$currentUser = User::getCurrent($database);
39
+		$template = $this->getTemplate($database);
40
+		$request = $this->getRequest($database);
41
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
+
43
+		if ($request->getStatus() === 'Closed') {
44
+			throw new ApplicationLogicException('Request is already closed');
45
+		}
46
+
47
+		if ($this->confirmEmailAlreadySent($request, $template)) {
48
+			return;
49
+		}
50
+
51
+		if ($this->checkReserveProtect($request, $currentUser)) {
52
+			return;
53
+		}
54
+
55
+		if ($this->confirmAccountCreated($request, $template)) {
56
+			return;
57
+		}
58
+
59
+		// I think we're good here...
60
+		$request->setStatus('Closed');
61
+		$request->setReserved(null);
62
+
63
+		Logger::closeRequest($database, $request, $template->getId(), null);
64
+
65
+		$request->save();
66
+
67
+		$this->processWelcome($template->getDefaultAction());
68
+
69
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
+		// be rolled back.
71
+
72
+		$this->getNotificationHelper()->requestClosed($request, $template->getName());
73
+		$sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
+		SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
+
76
+		$this->sendMail($request, $template->getText(), $currentUser, false);
77
+
78
+		$this->redirect();
79
+	}
80
+
81
+	/**
82
+	 * @param PdoDatabase $database
83
+	 *
84
+	 * @return EmailTemplate
85
+	 * @throws ApplicationLogicException
86
+	 */
87
+	protected function getTemplate(PdoDatabase $database)
88
+	{
89
+		$templateId = WebRequest::postInt('template');
90
+		if ($templateId === null) {
91
+			throw new ApplicationLogicException('No template specified');
92
+		}
93
+
94
+		/** @var EmailTemplate $template */
95
+		$template = EmailTemplate::getById($templateId, $database);
96
+		if ($template === false || !$template->getActive()) {
97
+			throw new ApplicationLogicException('Invalid or inactive template specified');
98
+		}
99
+
100
+		return $template;
101
+	}
102
+
103
+	/**
104
+	 * @param Request       $request
105
+	 * @param EmailTemplate $template
106
+	 *
107
+	 * @return bool
108
+	 */
109
+	protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
+	{
111
+		if ($this->checkEmailAlreadySent($request)) {
112
+			$this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
+
114
+			return true;
115
+		}
116
+
117
+		return false;
118
+	}
119
+
120
+	protected function checkEmailAlreadySent(Request $request)
121
+	{
122
+		if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
+			return true;
124
+		}
125
+
126
+		return false;
127
+	}
128
+
129
+	protected function checkReserveProtect(Request $request, User $currentUser)
130
+	{
131
+		$reservationId = $request->getReserved();
132
+
133
+		if ($reservationId !== 0 && $reservationId !== null) {
134
+			if ($currentUser->getId() !== $reservationId) {
135
+				SessionAlert::error("Request is reserved by someone else.");
136
+				$this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
+				return true;
138
+			}
139
+		}
140
+
141
+		return false;
142
+	}
143
+
144
+	/**
145
+	 * @param Request       $request
146
+	 * @param EmailTemplate $template
147
+	 *
148
+	 * @return bool
149
+	 * @throws \Waca\Exceptions\CurlException
150
+	 */
151
+	protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
+	{
153
+		if ($this->checkAccountCreated($request, $template)) {
154
+			$this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
+
156
+			return true;
157
+		}
158
+
159
+		return false;
160
+	}
161
+
162
+	protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
+	{
164
+		if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
+			$parameters = array(
166
+				'action'  => 'query',
167
+				'list'    => 'users',
168
+				'format'  => 'php',
169
+				'ususers' => $request->getName(),
170
+			);
171
+
172
+			$content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
+				$parameters);
174
+
175
+			$apiResult = unserialize($content);
176
+			$exists = !isset($apiResult['query']['users']['0']['missing']);
177
+
178
+			if (!$exists) {
179
+				return true;
180
+			}
181
+		}
182
+
183
+		return false;
184
+	}
185
+
186
+	/**
187
+	 * @param Request $request
188
+	 * @param string  $mailText
189
+	 * @param User    $currentUser
190
+	 * @param boolean $ccMailingList
191
+	 */
192
+	protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
+	{
194
+		$requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
+		$requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
+
197
+		$request->setEmailSent(true);
198
+		$request->save();
199
+	}
200
+
201
+	/**
202
+	 * @param Request       $request
203
+	 * @param EmailTemplate $template
204
+	 * @param string        $templateName
205
+	 *
206
+	 * @throws Exception
207
+	 * @return void
208
+	 */
209
+	protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
+	{
211
+		$this->assignCSRFToken();
212
+
213
+		$this->assign('request', $request->getId());
214
+		$this->assign('template', $template->getId());
215
+
216
+		$this->assign('updateversion', $request->getUpdateVersion());
217
+
218
+		$this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
+		$this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
+		$this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
+
222
+		$this->setTemplate($templateName);
223
+	}
224
+
225
+	/**
226
+	 * @param string $action
227
+	 *
228
+	 * @throws ApplicationLogicException
229
+	 */
230
+	final protected function processWelcome(string $action): void
231
+	{
232
+		$database = $this->getDatabase();
233
+		$currentUser = User::getCurrent($database);
234
+
235
+		if ($action !== EmailTemplate::CREATED) {
236
+			return;
237
+		}
238
+
239
+		if ($currentUser->getWelcomeTemplate() === null) {
240
+			return;
241
+		}
242
+
243
+		if (WebRequest::postBoolean('skipAutoWelcome')) {
244
+			return;
245
+		}
246
+
247
+		$this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
+	}
249 249
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@
 block discarded – undo
133 133
         if ($reservationId !== 0 && $reservationId !== null) {
134 134
             if ($currentUser->getId() !== $reservationId) {
135 135
                 SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
136
+                $this->redirect('/viewRequest', null, ['id' => $request->getId()]);
137 137
                 return true;
138 138
             }
139 139
         }
Please login to merge, or discard this patch.