diff --git a/project2/.gitignore b/project2/.gitignore new file mode 100644 index 0000000..66281f9 --- /dev/null +++ b/project2/.gitignore @@ -0,0 +1,4 @@ +config.php +config* +*config* +*.log diff --git a/project2/README.md b/project2/README.md new file mode 100644 index 0000000..e69de29 diff --git a/project2/home.php b/project2/home.php new file mode 100644 index 0000000..2d926f3 --- /dev/null +++ b/project2/home.php @@ -0,0 +1,10 @@ + + +

Welcome,

+ \ No newline at end of file diff --git a/project2/lib/README.md b/project2/lib/README.md new file mode 100644 index 0000000..e69de29 diff --git a/project2/lib/db.php b/project2/lib/db.php new file mode 100644 index 0000000..207a275 --- /dev/null +++ b/project2/lib/db.php @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/project2/lib/helpers.php b/project2/lib/helpers.php new file mode 100644 index 0000000..9eb5c61 --- /dev/null +++ b/project2/lib/helpers.php @@ -0,0 +1,79 @@ + \ No newline at end of file diff --git a/project2/lib/index.php b/project2/lib/index.php new file mode 100644 index 0000000..969a1c4 --- /dev/null +++ b/project2/lib/index.php @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/project2/login.php b/project2/login.php new file mode 100644 index 0000000..246d094 --- /dev/null +++ b/project2/login.php @@ -0,0 +1,93 @@ + +
+
+ + + + + +
+
+Invalid email
"; + } + + if ($isValid) { + $db = getDB(); + if (isset($db)) { + + if(isset($email)){ + $stmt = $db->prepare("SELECT id, email, username, password from Users WHERE email = :email LIMIT 1"); + }elseif(isset($username)){ + $stmt = $db->prepare("SELECT id, email, username, password from Users WHERE username = :username LIMIT 1"); + } + + if(isset($email)){ + $params = array(":email" => $email); + }elseif(isset($username)){ + $params = array(":username" => $username); + } + $r = $stmt->execute($params); + //echo "db returned: " . var_export($r, true); + $e = $stmt->errorInfo(); + if ($e[0] != "00000") { + //echo "uh oh something went wrong: " . var_export($e, true); + flash("Something went wrong, please try again"); + } + $result = $stmt->fetch(PDO::FETCH_ASSOC); + if ($result && isset($result["password"])) { + $password_hash_from_db = $result["password"]; + if (password_verify($password, $password_hash_from_db)) { + $stmt = $db->prepare(" +SELECT Roles.name FROM Roles JOIN UserRoles on Roles.id = UserRoles.role_id where UserRoles.user_id = :user_id and Roles.is_active = 1 and UserRoles.is_active = 1"); + $stmt->execute([":user_id" => $result["id"]]); + $roles = $stmt->fetchAll(PDO::FETCH_ASSOC); + + unset($result["password"]);//remove password so we don't leak it beyond this page + //let's create a session for our user based on the other data we pulled from the table + $_SESSION["user"] = $result;//we can save the entire result array since we removed password + if ($roles) { + $_SESSION["user"]["roles"] = $roles; + } + else { + $_SESSION["user"]["roles"] = []; + } + //on successful login let's serve-side redirect the user to the home page. + flash("Log in successful"); + die(header("Location: home.php")); + } + else { + flash("Username or Password incorrect"); + } + } + else { + flash("Username or Password incorrect"); + } + } + } + else { + flash("There was a validation issue"); + } +} +?> + + + \ No newline at end of file diff --git a/project2/partials/README.md b/project2/partials/README.md new file mode 100644 index 0000000..e69de29 diff --git a/project2/partials/flash.php b/project2/partials/flash.php new file mode 100644 index 0000000..03758ae --- /dev/null +++ b/project2/partials/flash.php @@ -0,0 +1,25 @@ + +
+ + + +
+

+
+ + +
+ \ No newline at end of file diff --git a/project2/partials/index.php b/project2/partials/index.php new file mode 100644 index 0000000..969a1c4 --- /dev/null +++ b/project2/partials/index.php @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/project2/partials/nav.php b/project2/partials/nav.php new file mode 100644 index 0000000..1fa432d --- /dev/null +++ b/project2/partials/nav.php @@ -0,0 +1,19 @@ + + + + diff --git a/project2/profile.php b/project2/profile.php new file mode 100644 index 0000000..00634e7 --- /dev/null +++ b/project2/profile.php @@ -0,0 +1,146 @@ + + +prepare("SELECT COUNT(1) as InUse from Users where email = :email"); + $stmt->execute([":email" => $email]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + $inUse = 1;//default it to a failure scenario + if ($result && isset($result["InUse"])) { + try { + $inUse = intval($result["InUse"]); + } + catch (Exception $e) { + + } + } + if ($inUse > 0) { + flash("Email already in use"); + //for now we can just stop the rest of the update + $isValid = false; + } + else { + $newEmail = $email; + } + } + $newUsername = get_username(); + if (get_username() != $_POST["username"]) { + $username = $_POST["username"]; + $stmt = $db->prepare("SELECT COUNT(1) as InUse from Users where username = :username"); + $stmt->execute([":username" => $username]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + $inUse = 1;//default it to a failure scenario + if ($result && isset($result["InUse"])) { + try { + $inUse = intval($result["InUse"]); + } + catch (Exception $e) { + + } + } + if ($inUse > 0) { + flash("Username already in use"); + //for now we can just stop the rest of the update + $isValid = false; + } + else { + $newUsername = $username; + } + } + + if ($isValid) { + //pull password from DB + $stmt = $db->prepare("SELECT password from Users WHERE id = :id LIMIT 1");//added + $r = $stmt->execute([":id" => get_user_id()]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); //added + $password_hash_from_db = $result["password"]; //added + + + + if ($r && password_verify($_POST["original"], $password_hash_from_db)) { + + $stmt = $db->prepare("UPDATE Users set email = :email, username= :username where id = :id"); + $r = $stmt->execute([":email" => $newEmail, ":username" => $newUsername, ":id" => get_user_id()]);//addded && and after - + + if (!empty($_POST["password"]) && !empty($_POST["confirm"] && !empty($_POST["original"]))) { + if ($_POST["password"] == $_POST["confirm"]) { + $password = $_POST["password"]; + $hash = password_hash($password, PASSWORD_BCRYPT); + $stmt = $db->prepare("UPDATE Users set password = :password where id = :id"); + $r = $stmt->execute([":id" => get_user_id(), ":password" => $hash]); + if ($r) { + flash("Reset Password"); + } + else { + flash("Error resetting password"); + } + //this one we'll do separate + } + flash("Updated profile"); + } + else { + flash("Error updating profile"); + } + //password is optional, so check if it's even set6 + //if so, then check if it's a valid reset request + //fetch/select fresh data in case anything changed + $stmt = $db->prepare("SELECT email, username from Users WHERE id = :id LIMIT 1"); + $stmt->execute([":id" => get_user_id()]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + if ($result) { + $email = $result["email"]; + $username = $result["username"]; + //let's update our session too + $_SESSION["user"]["email"] = $email; + $_SESSION["user"]["username"] = $username; + } + else { + + } + } + else { + flash("Invalid Password"); + } + + + } + +} +?> +
+
+ Current Email: + Current Username: + Role: + + + + + + + + + + + + +
+
+ + +"; + } + else { + flash("Passwords don't match"); + $isValid = false; + } + if (!isset($email) || !isset($password) || !isset($confirm)) { + $isValid = false; + } + //TODO other validation as desired, remember this is the last line of defense + if ($isValid) { + $hash = password_hash($password, PASSWORD_BCRYPT); + $db = getDB(); + if (isset($db)) { + //here we'll use placeholders to let PDO map and sanitize our data + $stmt = $db->prepare("INSERT INTO Users(email, username, password) VALUES(:email,:username, :password)"); + //here's the data map for the parameter to data + $params = array(":email" => $email, ":username" => $username, ":password" => $hash); + $r = $stmt->execute($params); + $e = $stmt->errorInfo(); + if ($e[0] == "00000") { + flash("Successfully registered! Please login."); + } + else { + if ($e[0] == "23000") {//code for duplicate entry + flash("Username or email already exists."); + } + else { + flash("An error occurred, please try again"); + } + } + } + } + else { + flash( "There was a validation issue"); + } +} +//safety measure to prevent php warnings +if (!isset($email)) { + $email = ""; +} +if (!isset($username)) { + $username = ""; +} +?> +
+
+ + + + + + + + + +
+
+ \ No newline at end of file diff --git a/project2/sql/init_db.php b/project2/sql/init_db.php new file mode 100644 index 0000000..c775641 --- /dev/null +++ b/project2/sql/init_db.php @@ -0,0 +1,85 @@ + 0){ + /*** + * Sort the array so queries are executed in anticipated order. + * Be careful with naming, 1-9 is fine, 1-10 has 10 run after #1 due to string sorting. + */ + ksort($sql); + echo "
" . var_export($sql, true) . "

"; + //connect to DB + $db = getDB(); + /*** + * Let's make this function a bit smarter to save DB calls for small dev plans (i.e., heroku) + */ + $stmt = $db->prepare("show tables"); + $stmt->execute(); + $count++; + $tables = $stmt->fetchAll(PDO::FETCH_ASSOC); + $t = []; + //convert it to a flat array + foreach($tables as $row){ + foreach($row as $key => $value) { + array_push($t, $value); + } + } + foreach($sql as $key => $value){ + echo "
Running: " . $key; + $lines = explode("(", $value, 2); + if(count($lines) > 0){ + //these lines attempt to extract the table info from any create commands + //to determine if they command should be skipped or not + $line = $lines[0]; + //clear out duplicate whitespace + $line = preg_replace('!\s+!', ' ', $line); + //remove create table command + $line = str_ireplace("create table", "", $line); + //remove if not exists command + $line = str_ireplace("if not exists", "", $line); + //remove backticks + $line = str_ireplace("`","",$line); + //trim whitespace in front and back + $line = trim($line); + if (in_array($line, $t)){ + echo "
Blocked from running, table found in 'show tables' results.
"; + continue; + } + } + $stmt = $db->prepare($value); + $result = $stmt->execute(); + $count++; + $error = $stmt->errorInfo(); + if($error && $error[0] !== '00000'){ + echo "
Error:
" . var_export($error,true) . "

"; + } + echo "
$key result: " . ($result>0?"Success":"Fail") . "
"; + } + echo "
Init complete, used approximately $count db calls.
"; + } + else{ + echo "Didn't find any files, please check the directory/directory contents/permissions"; + } + $db = null; +} +catch(Exception $e){ + echo $e->getMessage(); + exit("Something went wrong"); +} +?> \ No newline at end of file diff --git a/project2/static/css/styles.css b/project2/static/css/styles.css new file mode 100644 index 0000000..1bdfbcb --- /dev/null +++ b/project2/static/css/styles.css @@ -0,0 +1,66 @@ +/* design intentionally made horrible to see who doesn't change it*/ +body { + font-family: Sans-seifs; + font-size: 1.5em; +} + +ul[class="nav"]{ + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; + background-color: #40E0D0; +} + +.nav > li { + float: left; +} + +.nav > li a { + display: block; + color: #ffffff; + text-align: center; + padding: 16px; + text-decoration: none; +} + +.nav > li a:hover { + background-color: #00CED1; +} + +.register{ + font-size: 1.5em; + width: 200px; + height: 200px; + margin: auto; + float: left; + padding: 10; +} + +.login{ + font-size: 1.5em; + width: 200px; + height: 200px; + margin: auto; + float: left; + padding: 10; + +} + +.home{ + font-size: 1.5em; + width: 200px; + height: 200px; + margin: auto; + float: left; + padding: 10; +} + +.profile{ + font-size: 1.5em; + width: 200px; + height: 200px; + margin: auto; + float: left; + padding: 10; +}