| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2020-06-30 19:05:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * OAuthKeys.php | 
					
						
							| 
									
										
										
										
											2020-06-30 19:05:35 +02:00
										 |  |  |  * Copyright (c) 2020 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, either version 3 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 19:05:35 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  | namespace FireflyIII\Support\System; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use Artisan; | 
					
						
							|  |  |  | use Crypt; | 
					
						
							| 
									
										
										
										
											2021-12-02 18:14:43 +01:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  | use Illuminate\Contracts\Encryption\DecryptException; | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  | use Laravel\Passport\Console\KeysCommand; | 
					
						
							| 
									
										
										
										
											2021-12-02 18:14:43 +01:00
										 |  |  | use Log; | 
					
						
							|  |  |  | use Psr\Container\ContainerExceptionInterface; | 
					
						
							|  |  |  | use Psr\Container\NotFoundExceptionInterface; | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Class OAuthKeys | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class OAuthKeys | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     private const PRIVATE_KEY = 'oauth_private_key'; | 
					
						
							|  |  |  |     private const PUBLIC_KEY  = 'oauth_public_key'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |     public static function verifyKeysRoutine(): void | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |         if (!self::keysInDatabase() && !self::hasKeyFiles()) { | 
					
						
							|  |  |  |             self::generateKeys(); | 
					
						
							|  |  |  |             self::storeKeysInDB(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (self::keysInDatabase() && !self::hasKeyFiles()) { | 
					
						
							|  |  |  |             self::restoreKeysFromDB(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!self::keysInDatabase() && self::hasKeyFiles()) { | 
					
						
							|  |  |  |             self::storeKeysInDB(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |     public static function keysInDatabase(): bool | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-12-02 18:14:43 +01:00
										 |  |  |         $privateKey = ''; | 
					
						
							|  |  |  |         $publicKey  = ''; | 
					
						
							|  |  |  |         // better check if keys are in the database:
 | 
					
						
							|  |  |  |         if (app('fireflyconfig')->has(self::PRIVATE_KEY) && app('fireflyconfig')->has(self::PUBLIC_KEY)) { | 
					
						
							|  |  |  |             try { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                 $privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data; | 
					
						
							|  |  |  |                 $publicKey  = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data; | 
					
						
							| 
									
										
										
										
											2022-03-29 15:00:29 +02:00
										 |  |  |             } catch (ContainerExceptionInterface|NotFoundExceptionInterface|FireflyException $e) { | 
					
						
							| 
									
										
										
										
											2021-12-02 18:14:43 +01:00
										 |  |  |                 Log::error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage())); | 
					
						
							|  |  |  |                 Log::error($e->getTraceAsString()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if ('' !== $privateKey && '' !== $publicKey) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |     public static function hasKeyFiles(): bool | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |         $private = storage_path('oauth-private.key'); | 
					
						
							|  |  |  |         $public  = storage_path('oauth-public.key'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return file_exists($private) && file_exists($public); | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |     public static function generateKeys(): void | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |         Artisan::registerCommand(new KeysCommand()); | 
					
						
							|  |  |  |         Artisan::call('passport:keys'); | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function storeKeysInDB(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $private = storage_path('oauth-private.key'); | 
					
						
							|  |  |  |         $public  = storage_path('oauth-public.key'); | 
					
						
							|  |  |  |         app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private))); | 
					
						
							|  |  |  |         app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public))); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2022-03-29 15:10:05 +02:00
										 |  |  |      * @throws ContainerExceptionInterface | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      * @throws NotFoundExceptionInterface | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  |     public static function restoreKeysFromDB(): bool | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         $privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data; | 
					
						
							|  |  |  |         $publicKey  = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data; | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $privateContent = Crypt::decrypt($privateKey); | 
					
						
							|  |  |  |             $publicContent  = Crypt::decrypt($publicKey); | 
					
						
							| 
									
										
										
										
											2022-03-29 15:00:29 +02:00
										 |  |  |         } catch (DecryptException $e) { | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  |             Log::error('Could not decrypt pub/private keypair.'); | 
					
						
							|  |  |  |             Log::error($e->getMessage()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // delete config vars from DB:
 | 
					
						
							|  |  |  |             app('fireflyconfig')->delete(self::PRIVATE_KEY); | 
					
						
							|  |  |  |             app('fireflyconfig')->delete(self::PUBLIC_KEY); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-29 15:00:29 +02:00
										 |  |  |         $private = storage_path('oauth-private.key'); | 
					
						
							|  |  |  |         $public  = storage_path('oauth-public.key'); | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |         file_put_contents($private, $privateContent); | 
					
						
							|  |  |  |         file_put_contents($public, $publicContent); | 
					
						
							| 
									
										
										
										
											2021-12-21 16:35:28 +01:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2019-10-19 09:37:35 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-30 07:33:06 +02:00
										 |  |  | } |