229 lines
7.6 KiB
C
229 lines
7.6 KiB
C
|
#ifndef ENCRYPT_H
|
||
|
#define ENCRYPT_H
|
||
|
#pragma once
|
||
|
|
||
|
#include "../thirdparty/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h"
|
||
|
|
||
|
#include <chrono>
|
||
|
#include <cstring>
|
||
|
#include <ctime>
|
||
|
#include <iomanip>
|
||
|
#include <iostream>
|
||
|
#include <sodium.h>
|
||
|
#include <string>
|
||
|
#include <thread>
|
||
|
#include <vector>
|
||
|
|
||
|
using std::pair;
|
||
|
using namespace std::chrono;
|
||
|
using std::cin;
|
||
|
using std::cout;
|
||
|
using std::flush;
|
||
|
using std::string;
|
||
|
using std::to_string;
|
||
|
using std::vector;
|
||
|
using std::this_thread::sleep_for;
|
||
|
/*
|
||
|
hash_password takes the password, and encrypts it. This needs to be done,
|
||
|
because storing passwords in plaintext is BAD, no matter if it's just for a school project!
|
||
|
|
||
|
verify_password takes in a password and the hashed password, and then does magic encryption
|
||
|
stuff(no, not really. It basically hashes the password with the same salt and other parameters, but
|
||
|
that's not that important to know) and to see if the password stored and the given password match.
|
||
|
call these whenever you are working with passwords.
|
||
|
so to check if passwords match, use something like verifypassword(customer.password,
|
||
|
someplainpassword) see libsodium documentation for more info
|
||
|
*/
|
||
|
|
||
|
string hash_password(string password);
|
||
|
bool verify_password(string hashed_password, string unhashed_password);
|
||
|
|
||
|
namespace data {
|
||
|
|
||
|
/*
|
||
|
start_db is the function that opens the database, and
|
||
|
if the necesary tables are not there, creates them.
|
||
|
db is the database, and is static to avoid multiple redefinition errors,
|
||
|
because multiple cpp files import this header.
|
||
|
TODO: remove this namespace, we didn't add more functions here like originally planned.
|
||
|
|
||
|
*/
|
||
|
SQLite::Database start_db();
|
||
|
static SQLite::Database db = start_db();
|
||
|
|
||
|
} // namespace data
|
||
|
|
||
|
/*
|
||
|
|
||
|
|
||
|
Record of who parked at what park_spot and at what time.
|
||
|
public interface-------------------------------------------
|
||
|
|
||
|
The constructors. one for creating new customers, the other one used by the
|
||
|
query functions to construct the object from information stored in the database.
|
||
|
|
||
|
clock_out is the function that gets called from customer.clock_out().
|
||
|
It verifies that the customer is clocking out at the correct parkspot, and saves
|
||
|
the current time of clocking out in end. It also calculates duration so it
|
||
|
doesn't have to be calculated more than once.
|
||
|
|
||
|
operator<< is << overload, can(should) be used for report generation.
|
||
|
|
||
|
|
||
|
// implementation stuff------------------------
|
||
|
start and end are time points representing when someone clocks in and out. they're from the chrono
|
||
|
namespace.
|
||
|
|
||
|
save and update save and update info in the database.
|
||
|
auto_increment pulls the highest id stored in the db, to be used in the constructor.
|
||
|
|
||
|
start_to_int() is used to convert the start timepoint to an integer that can be saved in the
|
||
|
database SQL datetime and chrono datetime don't seem the most compatible.
|
||
|
|
||
|
We choose chrono because it's the recomended way from c++11 onwards, and is more typesafe and
|
||
|
acurate https://stackoverflow.com/questions/36095323/what-is-the-difference-between-chrono-and-ctime
|
||
|
but, it does not have parsing and formatting for human readable time.
|
||
|
It will get that in c++20, but that's a little too late for us :(
|
||
|
So for now, conversion to/from ctime objects it is....
|
||
|
|
||
|
*/
|
||
|
|
||
|
class Park_time {
|
||
|
public:
|
||
|
Park_time(int c_id, int s_id);
|
||
|
Park_time(int id_, int customer_id_, int spot_id_, int start_, int duration_);
|
||
|
int id;
|
||
|
int customer_id;
|
||
|
int spot_id;
|
||
|
int duration;
|
||
|
|
||
|
void clock_out(int c_id, int s_id);
|
||
|
friend std::ostream& operator<<(std::ostream& os, const Park_time& pt);
|
||
|
|
||
|
private:
|
||
|
high_resolution_clock::time_point start;
|
||
|
high_resolution_clock::time_point end;
|
||
|
void save_db();
|
||
|
void update_db();
|
||
|
int auto_increment_db(); // helper
|
||
|
int start_to_int(); // helper
|
||
|
};
|
||
|
|
||
|
// function that slowly outputs each character one by one
|
||
|
void text_animation(const string& text, unsigned int pause_time);
|
||
|
|
||
|
/*
|
||
|
enum classes make it easy to represent categories.
|
||
|
So you can use something like Vehicle_type::twowheeler instead of 2 in code, so you know it's that.
|
||
|
but under the hood, it's still an int.
|
||
|
This is so you don't have to polute the global namespace with unnecesary variables.
|
||
|
enum classes do not permit implicit conversion between int and the enum class, and are in the
|
||
|
Enumclass:: scope in contrast to plain enums. https://en.cppreference.com/w/cpp/language/enum
|
||
|
*/
|
||
|
enum class Vehicle_type { twoweeler = 1, fourweeler = 2 };
|
||
|
|
||
|
/*
|
||
|
Customer constructors do the same stuff as all the other constructors.
|
||
|
clock_in and out create and modify park_time objects and store them to
|
||
|
park_instances. Technically, now that we have a working db, we don't need it.
|
||
|
It might have some performance benefits to keeping it, though.
|
||
|
TODO: test or fix this.
|
||
|
save, update, delete and auto increment are the same as in park_time but for customers.
|
||
|
*/
|
||
|
|
||
|
class Customer {
|
||
|
public:
|
||
|
int id;
|
||
|
string name;
|
||
|
string password;
|
||
|
Vehicle_type vehicle;
|
||
|
string telephone;
|
||
|
int role;
|
||
|
Customer(string name_, string password_, Vehicle_type vehicle_, string telephone_, int role_);
|
||
|
Customer(int id_, string name_, string password_, Vehicle_type vehicle_,
|
||
|
vector<Park_time> instances, string telephone_, int role_);
|
||
|
void clock_in(int s_id);
|
||
|
void clock_out(int s_id);
|
||
|
bool parked();
|
||
|
int parked_at();
|
||
|
|
||
|
void update_db();
|
||
|
void delete_db();
|
||
|
|
||
|
private:
|
||
|
vector<Park_time> park_instances;
|
||
|
void save_db();
|
||
|
int auto_increment_db();
|
||
|
};
|
||
|
|
||
|
class Park_spot {
|
||
|
public:
|
||
|
int id;
|
||
|
bool taken;
|
||
|
int parked_customer;
|
||
|
Vehicle_type v_type;
|
||
|
|
||
|
Park_spot(Vehicle_type v_type_);
|
||
|
Park_spot(int id_, bool taken_, int parked, Vehicle_type v_type_);
|
||
|
void clock(Customer& c_customer);
|
||
|
|
||
|
private:
|
||
|
void save_db();
|
||
|
void update_db();
|
||
|
void delete_db();
|
||
|
int auto_increment_db();
|
||
|
};
|
||
|
|
||
|
/*these are the functions that search the database and create objects from it.
|
||
|
query_parktimes_for_customer searches for the parktimes that are needed in
|
||
|
customer initialisaiton. generally, i see no use outside of that.
|
||
|
|
||
|
query_customer_with_name searches for customer data by name.
|
||
|
NOTE: query_customer_with_name has been removed, nothing is using it
|
||
|
query_customer_with_id does what the above does, but with id.
|
||
|
|
||
|
query_parkspot_with_id does what the above do, but with a vector and not to the db.
|
||
|
|
||
|
populate_spots is used to query for all the park_spots in db and return them in a vector.
|
||
|
We can keep that in memory to reduce calls to the db, but increasing the memory footprint of this
|
||
|
program
|
||
|
|
||
|
reports_from_x functions query the db for parktimes with various conditions
|
||
|
current_status_parkspots takes in a vector and outputs the status of them
|
||
|
|
||
|
*/
|
||
|
|
||
|
vector<Park_time> query_parktimes_for_customer(int cid);
|
||
|
Customer query_customer_with_id(int id);
|
||
|
Park_spot query_parkspot_with_id(int id, vector<Park_spot>& parkspots);
|
||
|
int query_role_customer(int id);
|
||
|
|
||
|
vector<Park_spot> populate_spots();
|
||
|
|
||
|
void reports_from_parkspot(int spotid, pair<int, int> period);
|
||
|
void reports_from_allparkspots(pair<int, int> period);
|
||
|
void current_status_parkspots(vector<Park_spot>& spots);
|
||
|
vector<Park_time> reports_from_customer(int cid, pair<int, int> period);
|
||
|
|
||
|
// interface functions
|
||
|
void interface(vector<Park_spot>& spots);
|
||
|
void interface_member(vector<Park_spot>& spots, Customer& c);
|
||
|
void interface_admin(vector<Park_spot>& spots);
|
||
|
void park(Customer& c, vector<Park_spot>& spots);
|
||
|
void new_customer();
|
||
|
void new_admin();
|
||
|
void new_parkspot(vector<Park_spot>& spots);
|
||
|
void edit_information(Customer&);
|
||
|
|
||
|
// time creation
|
||
|
pair<int, int> create_month_period();
|
||
|
pair<int, int> create_week_period();
|
||
|
|
||
|
// report functions
|
||
|
void report_single_spot(bool weekly = false);
|
||
|
void report_all_spots(bool weekly = false);
|
||
|
void report_customer(int customerID, bool weekly = false);
|
||
|
|
||
|
// confirmation function
|
||
|
bool confirm();
|
||
|
#endif
|