189 lines
		
	
	
		
			No EOL
		
	
	
		
			5.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			No EOL
		
	
	
		
			5.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| session_start();
 | |
| 
 | |
| define('IDENTITIES_FILE', 'identities.json');
 | |
| define('PRESENT_FILE', 'present.json');
 | |
| 
 | |
| define('NAME_PATTERN', "^([ a-zA-Z0-9'\-]){1,30}$");
 | |
| define('MAC_PATTERN', "^([0-9A-Fa-f]{2}[:-s]){5}([0-9A-Fa-f]{2})$");
 | |
| define('PAGE_TITLE', 'CZI Presence Detector');
 | |
| 
 | |
| $present = json_decode(file_get_contents(PRESENT_FILE), true);
 | |
| 
 | |
| $tz = 'Europe/Berlin';
 | |
| $datetime = new DateTime("now", new DateTimeZone($tz));
 | |
| $datetime->setTimestamp($present["timestamp"]);
 | |
| 
 | |
| 
 | |
| function hash_mac($mac)
 | |
| {
 | |
|   $normalized_mac = str_replace('-', ':', strtolower($mac));
 | |
|   $hashed_mac = hash('sha256', $normalized_mac);
 | |
|   return $hashed_mac;
 | |
| }
 | |
| 
 | |
| function add_identity($name, $mac)
 | |
| {
 | |
|   if (
 | |
|     preg_match('/' . NAME_PATTERN . '/', $name) != 1 ||
 | |
|     preg_match('/' . MAC_PATTERN . '/', $mac) != 1
 | |
|   ) {
 | |
|     http_response_code(400);
 | |
|     die("Bad data");
 | |
|   }
 | |
| 
 | |
|   $hashed_mac = hash_mac($mac);
 | |
| 
 | |
|   $identities = json_decode(file_get_contents(IDENTITIES_FILE), true);
 | |
| 
 | |
|   $url = strtok($_SERVER['REQUEST_URI'], '?');
 | |
| 
 | |
|   foreach ($identities as $identity) {
 | |
|     if ($identity['name'] == $name) {
 | |
|       $_SESSION['form_success'] = false;
 | |
|       $_SESSION['form_success_message'] = 'Name already in use, please choose a different one.';
 | |
|       header("Location: " . $url, true, 303);
 | |
|       exit();
 | |
|     }
 | |
|     if ($identity['mac_hash'] == $hashed_mac) {
 | |
|       $_SESSION['form_success'] = false;
 | |
|       $_SESSION['form_success_message'] = 'MAC already set up, please remove it first to change name.';
 | |
|       header("Location: " . $url, true, 303);
 | |
|       exit();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   array_push($identities, array("name" => $name, "mac_hash" => $hashed_mac));
 | |
|   file_put_contents(IDENTITIES_FILE, json_encode($identities));
 | |
| 
 | |
|   $_SESSION['form_success'] = true;
 | |
|   $_SESSION['form_success_message'] = 'Identity successfully saved.';
 | |
|   header("Location: " . $url, true, 303);
 | |
|   exit();
 | |
| }
 | |
| 
 | |
| function remove_identity($mac)
 | |
| {
 | |
|   if (preg_match('/' . MAC_PATTERN . '/', $mac) != 1) {
 | |
|     http_response_code(400);
 | |
|     die("Bad data");
 | |
|   }
 | |
| 
 | |
|   $hashed_mac = hash_mac($mac);
 | |
| 
 | |
|   $url = strtok($_SERVER['REQUEST_URI'], '?');
 | |
| 
 | |
|   $identities = json_decode(file_get_contents(IDENTITIES_FILE), true);
 | |
| 
 | |
|   $new_identities = array();
 | |
| 
 | |
|   foreach ($identities as $identity) {
 | |
|     if ($identity['mac_hash'] != $hashed_mac) {
 | |
|       array_push($new_identities, $identity);
 | |
|     }
 | |
|   }
 | |
|   file_put_contents(IDENTITIES_FILE, json_encode($new_identities));
 | |
| 
 | |
|   if (count($identities) > count($new_identities)) {
 | |
|     $_SESSION['form_success'] = true;
 | |
|     $_SESSION['form_success_message'] = 'Identity successfully removed.';
 | |
|   } else {
 | |
|     $_SESSION['form_success'] = false;
 | |
|     $_SESSION['form_success_message'] = 'Identity not found.';
 | |
|   }
 | |
|   header("Location: " . $url, true, 303);
 | |
|   exit();
 | |
| }
 | |
| 
 | |
| if ($_SERVER['REQUEST_METHOD'] == "POST") {
 | |
|   if (
 | |
|     isset($_POST['name']) &&
 | |
|     isset($_POST['mac'])
 | |
|   ) {
 | |
|     add_identity($_POST['name'], $_POST['mac']);
 | |
|   } else if (isset($_POST['remove-mac'])) {
 | |
|     remove_identity($_POST['remove-mac']);
 | |
|   }
 | |
| }
 | |
| ?>
 | |
| 
 | |
| <html>
 | |
| 
 | |
| <head>
 | |
|   <title><?php echo PAGE_TITLE; ?></title>
 | |
|   <meta charset="UTF-8">
 | |
|   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
|   <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
 | |
|   <script src="bootstrap/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
 | |
| </head>
 | |
| 
 | |
| <body>
 | |
|   <nav class="navbar navbar-light bg-light justify-content-between" style="padding: 0">
 | |
|     <span class="navbar-brand mb-0 h1" style="padding-left: 1rem"><?php echo PAGE_TITLE; ?></span>
 | |
|   </nav>
 | |
|   <div id="content" style="padding: 2rem;">
 | |
|     <h2>Jetzt gerade im CZI <small>(letztes Update von <?php echo $datetime->format('H:i:s d.m.Y'); ?>)</small></h2><br>
 | |
|     <table class="table">
 | |
|       <thead>
 | |
|         <tr>
 | |
|           <th>Name</th>
 | |
|         </tr>
 | |
|       </thead>
 | |
|       <?php
 | |
|       foreach ($present["names"] as $name) {
 | |
|       ?>
 | |
|         <tr>
 | |
|           <td><?php echo $name; ?></td>
 | |
|         </tr>
 | |
|       <?php
 | |
|       }
 | |
|       ?>
 | |
|     </table>
 | |
|     <br><br>
 | |
|     <?php
 | |
|     if (isset($_SESSION['form_success'])) {
 | |
|       if ($_SESSION['form_success'] === false) {
 | |
|     ?>
 | |
|         <div class="alert alert-danger" role="alert">
 | |
|           <?php echo $_SESSION['form_success_message']; ?>
 | |
|         </div>
 | |
|       <?php
 | |
|       } else if ($_SESSION['form_success'] === true) {
 | |
|       ?>
 | |
|         <div class="alert alert-success" role="alert">
 | |
|           <?php echo $_SESSION['form_success_message']; ?>
 | |
|         </div>
 | |
|     <?php
 | |
|       }
 | |
|       unset($_SESSION['form_success']);
 | |
|       unset($_SESSION['form_success_message']);
 | |
|     } ?>
 | |
|     <div class="row justify-content-start row-cols-sm-1 row-cols-md-1 row-cols-lg-2 row-cols-xl-3">
 | |
|       <div class="col col-md-4">
 | |
|         <div class="card" style="max-width: 30rem;">
 | |
|           <div class="card-body">
 | |
|             <h5 class="card-title">Neues Gerät tracken</h5>
 | |
|             <form method="POST">
 | |
|               <input class="form-control" type="text" name="name" pattern="<?php echo NAME_PATTERN; ?>" placeholder="Name" value="" required /><br>
 | |
|               <input class="form-control" type="text" name="mac" pattern="<?php echo MAC_PATTERN; ?>" placeholder="MAC-Adresse" value="" required /><br>
 | |
|               <button class="btn btn-primary" type="submit">Speichern</button>
 | |
|             </form>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div class="col col-md-4">
 | |
|         <div class="card" style="max-width: 30rem;">
 | |
|           <div class="card-body">
 | |
|             <h5 class="card-title">Gerät entfernen</h5>
 | |
|             <form method="POST">
 | |
|               <input class="form-control" type="text" name="remove-mac" pattern="<?php echo MAC_PATTERN; ?>" placeholder="MAC-Adresse" value="" required /><br>
 | |
|               <button class="btn btn-primary" type="submit">Entfernen</button>
 | |
|             </form>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
|     </div>
 | |
|   </div>
 | |
| </body>
 | |
| 
 | |
| </html>
 |