109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Core;
 | |
| 
 | |
| use \Exception;
 | |
| 
 | |
| /**
 | |
|  * Decides what is allowed and what not
 | |
|  * TODO: ...
 | |
|  */
 | |
| class AccessControl
 | |
| {
 | |
|     public App $app;
 | |
| 
 | |
|     private array  $acl;
 | |
|     private string $current_page;
 | |
| 
 | |
|     public function __construct(App $app)
 | |
|     {
 | |
|         $this->app = $app;
 | |
| 
 | |
|         $this->acl = [
 | |
|             // routes that need power level 1 and up
 | |
|             [
 | |
|                 "routes" => [
 | |
|                     "race/simulator.php",
 | |
|                     "race/configure/*"
 | |
|                 ],
 | |
|                 "catcher" => [
 | |
|                     "name" => "page",
 | |
|                     "args" => 1,
 | |
|                 ],
 | |
|             ],
 | |
|             // routes that dont need any auth
 | |
|             [
 | |
|                 "routes" => [
 | |
|                     "*" // this is dumb but security is not that important :D
 | |
|                 ],
 | |
|                 "catcher" => [
 | |
|                     "name" => "nothing",
 | |
|                 ],
 | |
|             ]
 | |
|         ];
 | |
| 
 | |
|         $this->current_page = substr(
 | |
|             $_SERVER["SCRIPT_NAME"],
 | |
|             strlen($this->app->config["root_url"])
 | |
|         );
 | |
| 
 | |
|         // TODO: add error handling
 | |
|         foreach ($this->acl as $key => $value)
 | |
|         {
 | |
|             $routes  = $value["routes"];
 | |
|             $catcher = $value["catcher"];
 | |
| 
 | |
|             foreach ($routes as $key => $value)
 | |
|             {
 | |
|                 // if the end of the route is an asterisk we match everything after it
 | |
|                 if ($value[-1] == '*')
 | |
|                 {
 | |
|                     // remove asterisk
 | |
|                     $value = substr($value, 0, -1);
 | |
|                     // check if string starts with
 | |
|                     if (strncmp($this->current_page, $value, strlen($value)) !== 0)
 | |
|                     {
 | |
|                         continue;
 | |
|                     }
 | |
|                 } else {
 | |
|                     // end is not an asterisk, match full string
 | |
|                     if ($value !== $this->current_page)
 | |
|                     {
 | |
|                         continue;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (isset($catcher["args"]))
 | |
|                 {
 | |
|                     call_user_func([$this, $catcher["name"]], $catcher["args"]);
 | |
|                 } else {
 | |
|                     call_user_func([$this, $catcher["name"]]);
 | |
|                 }
 | |
| 
 | |
|                 return;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         throw new Exception("Could not find current page in access control list, did you add it?");
 | |
|     }
 | |
| 
 | |
|     private function page(int $power_level): void
 | |
|     {
 | |
|         if (!$this->app->user->logged_in || !($this->app->user->power_level >= $power_level))
 | |
|         {
 | |
|             http_response_code(401);
 | |
|             $this->app->view("template/header", ["title" => "Ingen tilgang!"]);
 | |
|             $this->app->view("App/Core/AccessControl/unauthorized");
 | |
|             $this->app->view("template/footer");
 | |
|             die();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Does... nothing! For when the page does not need any access control.
 | |
|      */
 | |
|     private function nothing(): void
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| } |