-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDatabase.php
More file actions
146 lines (129 loc) · 4.29 KB
/
Database.php
File metadata and controls
146 lines (129 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
* The Database class handles abstraction of the MySQL database
*/
class Database
{
/**
* Database driver class
* @var Medoo
*/
private $medoo;
/**
* Response code constants
*/
const PASS_OKAY = 'pass_okay';
const ERROR_PASS_MISMATCH = 'pass_mismatch';
const ERROR_ENTRIES_TOO_OLD = 'entries_too_old';
/**
* Setup class
* @param array $config configuration object for the database
*/
public function __construct($config)
{
$this->medoo = new medoo($config);
}
/**
* Log a pass attempt to the database
* @param string $cardID the full card ID
* @param boolean $access true if access was granted, false otherwise
* @param string $username the username of the owner of the card, if known, defaults to null otherwise
* @param string $reason the reason for the decision, if known, defaults to null otherwise
* @return void
*/
public function logAttempt($cardID, $access, $username = null, $reason = null)
{
$this->medoo->insert('attempts', [
'card_id' => $cardID,
'access_granted' => $access,
'username' => $username,
'reason' => $reason,
]);
}
/**
* Validate that the last two pass entries are correct
* 1) last two pass scans are identical
* 2) last two pass scans are maximum 10 mins before now
* @return string one of the constants above
*/
public function validatePassAttempt()
{
// Get the last two failures from the database
$candidates = $this->medoo->select('attempts', ['timestamp', 'card_id'], [
'access_granted' => false,
'LIMIT' => 2,
'ORDER' => 'timestamp DESC'
]);
$pass_first = $candidates[0]['card_id'];
$pass_second = $candidates[1]['card_id'];
$time_second = $candidates[1]['timestamp'];
// Last two passes must match
if ($pass_first !== $pass_second) {
return self::ERROR_PASS_MISMATCH;
}
// Timestamp must be no later than ten minutes ago
$deadline = (new \DateTime())->sub(new \DateInterval('PT10M'));
$entry = new DateTime($time_second);
if ($entry < $deadline) {
return self::ERROR_ENTRIES_TOO_OLD;
}
// All passed
return self::PASS_OKAY;
}
/**
* Return the last valid pass ID
* @return string full ID of the pass
*/
public function getLastRefusedPass()
{
// Get the last failure from the database
$query = $this->medoo->select('attempts', ['card_id'], [
'access_granted' => false,
'LIMIT' => 1,
'ORDER' => 'timestamp DESC'
]);
return $query[0]['card_id'];
}
/**
* Return an associative array of [username] => [timestamp]
* which contains the last timestamp on which a specific username
* successfully opened the door
*
* @return array
*/
public function getLastEntries()
{
// Query for usernames and last timestamps of access
$query = $this->medoo->query(
'SELECT `username`, MAX(`timestamp`) AS last_entry
FROM `attempts`
WHERE `username` IS NOT NULL
AND `access_granted` = 1
GROUP BY `username`'
)->fetchAll();
// Construct associative array
$output = [];
$tz = new DateTimeZone('Europe/Amsterdam');
$one_week_ago = new DateTime('-1 week', $tz);
$one_month_ago = new DateTime('-1 month', $tz);
foreach ($query as $row) {
// Convert to human diff (1 month ago, 1 week ago, etc..)
$entry = new DateTime($row['last_entry'], $tz);
$result = '';
if (!$entry) {
$result = 'Voor 1 september 2015 (of nooit)';
}
elseif ($entry < $one_month_ago) {
$result = 'Meer dan een maand geleden';
}
elseif ($entry < $one_week_ago) {
$result = 'Meer dan een week geleden';
}
else {
$result = 'Minder dan een week geleden';
}
$output[$row['username']] = $result;
}
return $output;
}
}