iwa-panda2

Manage Weather Data by International Weather Agency (Version 2)
Log | Files | Refs | README

commit 5a4e32ab1380ea26fa42f5867f261bba99d5e93b
parent b5a37a91fc09122509f2531dd6d0895c78cd3661
Author: MoiBaguette <[email protected]>
Date:   Mon, 12 Jun 2023 17:50:01 +0200

werkende login

Diffstat:
AController/api/api.php | 10++++++++++
AController/login/login_get.php | 4++++
AController/login/login_post.php | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AController/logout/logout.php | 12++++++++++++
AController/user/add_get.php | 5+++++
AController/user/add_post.php | 37+++++++++++++++++++++++++++++++++++++
MLollipop/DatabaseObject.php | 28++++++++++++++++++++++++++++
MLollipop/Router.php | 17+++++++++++++----
MLollipop/Template.php | 48++++++++++++++++++++++++++++++++++--------------
MModel/Login_handler.php | 2+-
AModel/Permission_User.php | 16++++++++++++++++
AModel/User.php | 17+++++++++++++++++
AModel/Utils.php | 36++++++++++++++++++++++++++++++++++++
Mindex.php | 54++++++++++++++++++++++++++++++++++++++++++------------
Aviews/add_user.html | 35+++++++++++++++++++++++++++++++++++
Aviews/api_test.html | 37+++++++++++++++++++++++++++++++++++++
Mviews/dashboard.html | 4++--
Aviews/login.html | 47+++++++++++++++++++++++++++++++++++++++++++++++
Dviews/login.php | 59-----------------------------------------------------------
19 files changed, 450 insertions(+), 92 deletions(-)

diff --git a/Controller/api/api.php b/Controller/api/api.php @@ -0,0 +1,9 @@ +<?php +$data = json_decode(file_get_contents('php://input'), true); +$token = $data['token']; +$responseData = array( + 'message' => 'Token received successfully', + 'token' => $token + ); +header('Content-Type: application/json'); +echo json_encode($responseData); +\ No newline at end of file diff --git a/Controller/login/login_get.php b/Controller/login/login_get.php @@ -0,0 +1,3 @@ +<?php + $templater = new Lollipop\Template(); + echo $templater->template("views/login.html", ["msg" => ""]); +\ No newline at end of file diff --git a/Controller/login/login_post.php b/Controller/login/login_post.php @@ -0,0 +1,73 @@ +<?php +const login = "email"; +const pwd = "password"; +class Login_handler +{ + function login():bool{ + $post_arr = Utils::post_to_array(); + $missing_fields = Utils::missing_fields($post_arr , [login, pwd]); + + if(sizeof($missing_fields) == 0){ + return ($this->authenticate($post_arr)); + }else{ + return false; + } + + } + function authenticate(array $post) : bool + //this function return true when user is autheticated uses set_globals to set $_SESSION variables + { + //create a SQLDatabase class + $db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "panda"); + //create a Database object class, with the table User + $u = $db->get(Model\User::class); + + //check if the email exists in db + if(!$u->load($post[login])){ + //email does not exist + return false; + }else{ + if(password_verify($post[pwd], $u->{pwd})){ + //authenticated -> set $_SESSION variables + $this->set_globals($u, $db); + return true; + } else { + //password did not match + return false; + } + } + } + + private function set_globals(Lollipop\DatabaseObject $u, Lollipop\SQLDatabase $db) + //this function sets Session variables which incluse + //email, first_name, last_name and array user_permissions + { + //start session and set + session_start(); + $u->load($u->get_primary()); + + foreach($u->getData() as $key => $data){ + if($key != pwd){ + $_SESSION[$key] = $data; + } + } + //get permissions form db and set sessions_permissions + $p = $db->all_where(Model\Permission_user::class, [login, $u->{login}]); + foreach($p as $permission){ + $user_permissions[] = $permission->id; + } + $_SESSION['user_permissions'] = $user_permissions; + } +} +function login_handler(){ + $templater = new Lollipop\Template(); + $login = new Login_handler(); + + if( $login->login()){ + header("Location: dashboard"); + exit(); + }else{ + echo $templater->template("views/login.html", ["msg" => "<p style=\"color:red;\">Incorrect username or password.</p>"]); + } +} +?> +\ No newline at end of file diff --git a/Controller/logout/logout.php b/Controller/logout/logout.php @@ -0,0 +1,11 @@ +<?php +function logout(){ + // Start the session + session_start(); + + // Unset all session variables + $_SESSION = array(); + + // Destroy the session + session_destroy(); +} +\ No newline at end of file diff --git a/Controller/user/add_get.php b/Controller/user/add_get.php @@ -0,0 +1,4 @@ + <?php + $templater = new Lollipop\Template(); + $template["msg"] = ""; + echo $templater->template("views/add_user.html", $template); +\ No newline at end of file diff --git a/Controller/user/add_post.php b/Controller/user/add_post.php @@ -0,0 +1,37 @@ +<?php +function add_user(string $pwd_key){ + $db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "panda"); + $u = $db->get(Model\User::class); + + $post_arr = Utils::post_to_array(); + $missing_fields = Utils::missing_fields($post_arr , $u->not_nullable); + + if(sizeof($missing_fields) > 0){ + foreach($missing_fields as $key => $data){ + if($post_arr[$key] == "") + $key .= "_error"; + $post_arr[$key] = $data; + } + return $post_arr; + } + + if($u->load($post_arr[$u->get_primary()])){ + return ["msg" => "<p style=\"color:red;\">this email address is already taken: {$post_arr[$u->get_primary()]} </p>"]; + }else{ + if($post_arr[$pwd_key]){ + $post_arr[$pwd_key] = password_hash($post_arr[$pwd_key], PASSWORD_DEFAULT); + } + foreach($u->column_names as $col){ + if($post_arr[$col] != ""){ + $u->$col = $post_arr[$col]; + } + } + if($u->add()) + return ["msg" => "<p style=\"color:green;\">succes</p>"]; + else + return ["msg" => "<p style=\"color:red;\">could not add user to database</p>"]; + } +} + + + diff --git a/Lollipop/DatabaseObject.php b/Lollipop/DatabaseObject.php @@ -17,6 +17,7 @@ namespace Lollipop { $this->db = $db; $this->primary = $this->get_primary(); $this->table = $this->get_table(); + $this->notNullable(); } abstract static function get_primary(): string; @@ -165,5 +166,32 @@ namespace Lollipop { { return $this->data; } + private function notNullable(){ + //non-auto-increment not-nullable collumn names query + $not_null = []; + $col_names = []; + $sql = " SELECT column_name, is_nullable, extra + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = '{$this->table}' + AND TABLE_SCHEMA = 'panda'"; + $stmt = $this->db->conn->prepare($sql); + $stmt->execute(); + $result = $stmt->get_result(); + + if ($result->num_rows == 0) { + return false; + } + while($tmp = $result->fetch_assoc()){ + if($tmp["is_nullable"] == 'NO'){ + if($tmp["extra"] == "auto_increment") + continue; + $not_null[] = $tmp["column_name"]; + } + $col_names[] = $tmp["column_name"]; + } + $this->data["not_nullable"] = $not_null; + $this->data["column_names"] = $col_names; + return true; + } } } \ No newline at end of file diff --git a/Lollipop/Router.php b/Lollipop/Router.php @@ -5,11 +5,16 @@ namespace Lollipop { { protected array $routes = []; protected string $path; + protected Template $temp; + + public function __construct($temp) { + $this->temp = $temp; + } protected function match(string $match, array &$route_vars): bool { - $route_split = explode('/', $this->path); - $match_split = explode('/', $match); + $route_split = explode('/', trim($this->path, '/ ')); + $match_split = explode('/', trim($match, '/ ')); if (sizeof($route_split) != sizeof($match_split)) { return false; @@ -63,9 +68,13 @@ namespace Lollipop { $vars = []; if ($this->match($route["match"], $vars)) { if (is_callable($route["func"])) { - return $route["func"]($vars); + $fil = $route["func"]($vars); + if (!is_null($fil)) + echo $this->temp->template($fil, $vars); + return; } else { - return $this->includeRoute($route["func"], $vars); + echo $this->temp->template($route["func"], $vars); + return; } } } diff --git a/Lollipop/Template.php b/Lollipop/Template.php @@ -38,6 +38,8 @@ use ErrorException; if ($c == '"' && !$in_string) { // string start $in_string = true; } else if ($c == '"') { // string end + $tokens[] = $buffer; + $buffer = ''; $in_string = false; } else if ($c == ' ' && !$in_string) { if ($buffer) { @@ -60,7 +62,7 @@ use ErrorException; $right = array_pop($tokens); $left = array_pop($tokens); - if ($left == null || $right == null) + if (is_null($left) || is_null($right)) throw new ErrorException("Stack is empty"); return $left + $right; @@ -69,7 +71,7 @@ use ErrorException; $right = array_pop($tokens); $left = array_pop($tokens); - if ($left == null || $right == null) + if (is_null($left) || is_null($right)) throw new ErrorException("Stack is empty"); return intval($left) - intval($right); @@ -78,7 +80,7 @@ use ErrorException; $right = array_pop($tokens); $left = array_pop($tokens); - if ($left == null || $right == null) + if (is_null($left) || is_null($right)) throw new ErrorException("Stack is empty"); return intval($left) * intval($right); @@ -87,7 +89,7 @@ use ErrorException; $right = array_pop($tokens); $left = array_pop($tokens); - if ($left == null || $right == null) + if (is_null($left) || is_null($right)) throw new ErrorException("Stack is empty"); return intval($left) / intval($right); @@ -96,7 +98,7 @@ use ErrorException; $right = array_pop($tokens); $left = array_pop($tokens); - if ($left == null || $right == null) + if (is_null($left) || is_null($right)) throw new ErrorException("Stack is empty"); return $left . $right; @@ -105,7 +107,7 @@ use ErrorException; "to_int" => function(array &$tokens) { $val = array_pop($val); - if ($val == null) + if (is_null($val)) throw new ErrorException("Stack is empty"); return inval($val); @@ -114,7 +116,7 @@ use ErrorException; "include" => function (array &$tokens) { $name = array_pop($tokens); - if (!$name) + if ($name == null) throw new ErrorException("Stack is empty"); include($name); @@ -122,25 +124,43 @@ use ErrorException; "eval" => function (array &$tokens) { $expr = array_pop($tokens); - if (!$expr) + if (is_null($expr)) throw new ErrorException("Stack is empty"); return eval("return ($expr);"); - } + }, + "format_if" => function (array &$stack) { + $format_false = array_pop($stack); + $format_true = array_pop($stack); + $expr = array_pop($stack); + + if (is_null($expr) || is_null($format_true) || is_null($format_false)) + throw new ErrorException("Stack is empty"); + + if ($expr == "") + return $format_false; + else + return str_replace("%%", $expr, $format_true); + }, ]; $stack = []; foreach ($tokens as $token) { - if ($token[0] != '!') { - $stack[] = array_key_exists($token, $data) ? $data[$token] : $token; + if ($token && $token[0] == '!') { + $val = $funcs[substr($token, 1)]($stack); + if (!is_null($val)) + $stack[] = $val; + } else if ($token && $token[0] == '$') { + $stack[] = array_key_exists(substr($token, 1), $data) ? $data[substr($token, 1)] : ""; } else { - $stack[] = $funcs[substr($token, 1)]($stack); + $stack[] = $token; } } - if (sizeof($stack) != 1) + if (sizeof($stack) > 1) throw new ErrorException("Stack-size is not 1"); - + if (sizeof($stack) == 0) + return ""; return $stack[0]; } } diff --git a/Model/Login_handler.php b/Model/Login_handler.php @@ -5,7 +5,7 @@ class Login_handler //this function return true when user is autheticated uses set_globals to set $_SESSION variables { //create a SQLDatabase class - $db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "lollipop"); + $db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "panda"); //create a Database object class, with the table User $u = $db->get(Model\User::class); diff --git a/Model/Permission_User.php b/Model/Permission_User.php @@ -0,0 +1,15 @@ +<?php +namespace Model { + class Permission_User extends \Lollipop\DatabaseObject + { + static function get_table(): string + { + return "permission_user"; + } + + static function get_primary(): string + { + return 'email'; + } + } +} +\ No newline at end of file diff --git a/Model/User.php b/Model/User.php @@ -0,0 +1,16 @@ +<?php + +namespace Model { + class User extends \Lollipop\DatabaseObject + { + static function get_table(): string + { + return "user"; + } + + static function get_primary(): string + { + return "email"; + } + } +} +\ No newline at end of file diff --git a/Model/Utils.php b/Model/Utils.php @@ -0,0 +1,35 @@ +<?php +Class Utils{ + static function post_to_array():array{ + $arr = []; + foreach ($_POST as $key => $value) { + $arr[$key] = $value; + } + return $arr; + } + + static function missing_fields($post, $not_nullable){ + $missing = []; + foreach($not_nullable as $column){ + if($post[$column] == NULL || $post[$column] == ""){ + $missing[$column] = "This field cannot be empty!"; + } + } + return $missing; + } + + function create_permission_radials():string{ + $db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "lollipop"); + //select the available permissions from the database + $all_p = $db->all(Permissions::class); + $radials = ""; + foreach($all_p as $db_permission){ + $radials .= "<div class=\"mb-3 form-check\"> + <input type=\"checkbox\" class=\"form-check-input\" name=\"permissions[]\" value=" . $db_permission->id . "\"> + <input type='hidden' value='-1' name='{$db_permission->name}'> + <label class=\"form-check-label\" for=" . $db_permission->name . ">" . $db_permission->name . "</label> + </div> "; + } + return $radials; + } +} +\ No newline at end of file diff --git a/index.php b/index.php @@ -1,24 +1,54 @@ <?php +use Lollipop\Template; require_once "utils/autoloader.php"; -$router = new Lollipop\Router(); - -$router->addRoute(["GET"], "/", "views/login.php"); -$router->addRoute(["POST"], "/login", "logic/login.php"); -$router->addRoute(["POST"], "/", function($vars){ - $data = []; - foreach ($_POST as $key => $value) { - $data[$key] = $value; - } - $t = new Lollipop\Template(); - $t->template("views/login.php", $data); +$templater = new Template(); +$router = new Lollipop\Router($templater); + +//login +$router->addRoute(["GET"], "/", "views/login.html"); +$router->addRoute(["POST"], "/login", function($vars){ + include "Controller/login/login_post.php"; + login_handler(); +}); + +//logout +$router->addRoute(["POST", "GET"], "/logout", function($vars){ + include "Controller/logout/logout.php"; + logout(); + return "views/login.html"; +}); + +//user +//add +$router->addRoute(["GET"], "/user/add", "views/add_user.html"); +$router->addRoute(["POST"], "/user/add", function(&$vars){ + include "Controller/user/add_post.php"; + $res = add_user("password"); + + foreach($res as $key => $data){ + $vars[$key] = $data; + } + + return "views/add_user.html"; +}); + +//dashboard +$router->addRoute(["GET"], "/dashboard", function(&$vars){ + session_start(); + $vars = ["key" => "poepie"]; + foreach($_SESSION as $key => $data){ + $vars[$key] = $data; + } + + return "views/dashboard.html"; }); -$router->addRoute(["GET"], "/dashboard", "views/dashboard.html"); $router->addRoute(["GET"], "/hdata", "views/hdata.html"); $router->addRoute(["GET"], "/api/:data", function($vars) { $key = new Key; $key->retrieveData($vars); }); $router->addRoute(['GET'], '/css/dashboard.css', "css/dashboard.css"); + $router->route(); \ No newline at end of file diff --git a/views/add_user.html b/views/add_user.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html lang="eng"> + <head> + <title>Add user</title> + <!-- Bootstrap CSS --> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"> + <link rel="stylesheet" type="text/css" href="/css/homepage.css"> + </head> + <body> + <div class="container"> + <h1>Add user</h1> + + <form action="/user/add" method="post"> + <div class="mb-3"> + <label for="first_name" class="form-label"><b>Voornaam:</b></label> + <input type="text" class="form-control" name="first_name" id="first_name" placeholder="{{$first_name_error "%%" "First name" !format_if }}" value="{{$first_name "%%" "" !format_if }}"> + </div> + <div class="mb-3"> + <label for="last_name" class="form-label"><b>last_name:</b></label> + <input type="text" class="form-control" name="last_name" id="last_name" placeholder="{{$last_name_error "%%" "Last name" !format_if}}" value="{{$last_name "%%" "" !format_if }}"> + </div> + <div class="mb-3"> + <label for="email" class="form-label"><b>Email:</b></label> + <input type="text" class="form-control" name="email" id="email" placeholder="{{$email_error "%%" "Email" !format_if}}" value="{{$email "%%" "" !format_if}}"> + </div> + <div class="mb-3"> + <label for="password" class="form-label"><b>Wachtwoord:</b></label> + <input type="password" class="form-control" name="password" id="password" placeholder="{{$email_error "%%" "******" !format_if}}"> + </div> + <button type="submit" class="btn btn-primary" name="submit">Add user</button> + </form> + {{$msg}} + </div> + </body> +</html> diff --git a/views/api_test.html b/views/api_test.html @@ -0,0 +1,36 @@ +<html> + <head> + + </head> + <body> + <script> + + // Create an object with the data to send + const data = { + + token: '3jvl7yb5sRr80s6lTdeOyxV9VTQZkCPRp7bKOWKFWxfL2vhsU4Hhpgcmz9qe0zEk' + }; + + // Send a POST request to the PHP endpoint + fetch('/api/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': data.token + }, + body: JSON.stringify(data) + }) + .then(response => response.json()) + .then(responseData => { + // Handle the response data from the PHP endpoint + console.log(responseData); + }) + .catch(error => { + // Handle any errors that occurred during the request + console.error(error); + }); + + </script> + </body> + +</html> +\ No newline at end of file diff --git a/views/dashboard.html b/views/dashboard.html @@ -17,13 +17,13 @@ <li><a href="#" class="a-big-logo"><IMG class="img-big-logo" SRC="/img/big-logo.png"></a></li> <li><a href="#" class="active">Dashboard</a></li> <li><a href="/hdata">Historic Data</a></li> - <li><a href="#">Logout</a></li> + <li><a href="/logout">Logout</a></li> </ul> </nav> <!-- HEADER --> <h1>Welcome "Role"</h1> - +<div> some info<br> first name:{{$first_name}}<br>last name:{{$last_name}}<br>email:{{$email}}<br> {{$key}}</div> <!-- DATA BLOCKS --> <div class="block1"> <div class="content"> diff --git a/views/login.html b/views/login.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <title>Login Page</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" + integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> +</head> +<body> + <div class="container mx-auto text-center"> + <div class="row"> + <div class="col-md-12 title"> + <h1>Welcome to Lollipop</h1> + <h4>Please log in</h4> + </div> + </div> + </div> + <div class="container mt-5"> + <div class="row justify-content-center"> + <div class="col-md-6"> + <div class="card"> + <div class="card-header">Login</div> + <div class="card-body"> + <form method="POST" action="/login"> + <div class="form-group"> + <label for="email">Email:</label> + <input type="email" class="form-control" id="email" name="email" + placeholder="Enter email"> + </div> + <div class="form-group"> + <label for="password">password:</label> + <input type="password" class="form-control" id="password" name="password" + placeholder="Enter password"> + </div> + <button type="submit" name='login_btn' class="btn btn-primary">Login</button> + </form> + </div> + <div class="row justify-content-center"> + {{$msg}} + </div> + </div> + </div> + </div> + </div> +</body> + +</html> +\ No newline at end of file diff --git a/views/login.php b/views/login.php @@ -1,58 +0,0 @@ -<!DOCTYPE html> -<?php - if (!isset($_SESSION['CREATED'])) { - $_SESSION['CREATED'] = time(); - } else if (time() - $_SESSION['CREATED'] > 1800) { - // session started more than 30 minutes ago - session_regenerate_id(true); // change session ID for the current session and invalidate old session ID - $_SESSION['CREATED'] = time(); // update creation time - } -?> -<html> -<head> - <title>Login Page</title> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" - integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> -</head> -<body> - <div class="container mx-auto text-center"> - <div class="row"> - <div class="col-md-12 title"> - <h1>Welcome to Lollipop</h1> - <h4>Please log in</h4> - </div> - </div> - </div> - <div class="container mt-5"> - <div class="row justify-content-center"> - <div class="col-md-6"> - <div class="card"> - <div class="card-header">Login</div> - <div class="card-body"> - <form method="POST" action="/"> - <div class="form-group"> - <label for="email">Email:</label> - <input type="email" class="form-control" id="email" name="email" - placeholder="Enter email"> - </div> - <div class="form-group"> - <label for="password">Password:</label> - <input type="password" class="form-control" id="password" name="password" - placeholder="Enter password"> - </div> - <button type="submit" name='login_btn' class="btn btn-primary">Login</button> - </form> - </div> - <div class="row justify-content-center"> - <?php - //display login $msg -// echo $msg; - ?> - </div> - </div> - </div> - </div> - </div> -</body> - -</html> -\ No newline at end of file