-
Notifications
You must be signed in to change notification settings - Fork 2
/
User.php
170 lines (142 loc) · 4.94 KB
/
User.php
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<?php
namespace Users;
/**
* Represents a user instance. Does not deal with authentication methods
* (e.g. passwords, OpenID, OAuth2).
*/
class User {
/**
* Cache the user instance.
*/
static $instance = null;
var $params;
var $is_auto_logged_in = false;
/**
* Construct a user instance from the given user parameters (from the database).
*/
function __construct($params) {
$this->params = $params;
}
function __toString() {
return "[User " . $this->getId() . ", " . $this->getEmail() . ", " . $this->getIdentity() . "]";
}
/**
* Get the current logged in user instance, or {@code null} if
* there is none, based on session variables.
*
* @return the {@link User} logged in or {@code null} if none
*/
static function getInstance(\Db\Connection $db) {
if (User::$instance === null) {
if (session_status() === PHP_SESSION_NONE) {
throw new UserStatusException("Session needs to be started before requesting User instance");
}
// try autologin if we don't have session variables set
$used_auto_login = false;
if (!isset($_SESSION['user_id']) && !isset($_SESSION['user_key']) && !isset($_SESSION['no_autologin'])) {
User::tryAutoLogin();
$used_auto_login = true;
}
// if the session variables are still not set after autologin, bail
if (!isset($_SESSION['user_id']) && !isset($_SESSION['user_key'])) {
return User::$instance;
}
// now try to find the valid user
$q = $db->prepare("SELECT * FROM user_valid_keys WHERE user_id=? AND user_key=? LIMIT 1");
$q->execute(array($_SESSION['user_id'], $_SESSION['user_key']));
if ($user = $q->fetch()) {
// find the associated user
User::$instance = User::findUser($db, $user['user_id']);
if (User::$instance) {
User::$instance->is_auto_logged_in = $used_auto_login;
}
}
}
return User::$instance;
}
function persist(\Db\Connection $db, $use_cookies = false) {
$user_key = sprintf("%04x%04x%04x%04x", rand(0,0xffff), rand(0,0xffff), rand(0,0xffff), rand(0,0xffff));
// create a new valid user key
$q = $db->prepare("INSERT INTO user_valid_keys SET user_id=?, user_key=?");
$q->execute(array($this->getId(), $user_key));
$_SESSION['user_id'] = $this->getId();
$_SESSION['user_key'] = $user_key;
unset($_SESSION['no_autologin']);
if ($use_cookies) {
$_COOKIE['autologin_id'] = $this->getId();
$_COOKIE['autologin_key'] = $user_key;
}
// delete old web keys
$days = \Openclerk\Config::get("autologin_expire_days");
$q = $db->prepare("DELETE FROM user_valid_keys WHERE user_id=? AND created_at < DATE_SUB(NOW(), INTERVAL $days DAY)");
$q->execute(array($this->getId()));
}
static function tryAutoLogin() {
if (isset($_COOKIE['autologin_id']) && isset($_COOKIE['autologin_key'])) {
$_SESSION['user_id'] = $_COOKIE['autologin_id'];
$_SESSION['user_key'] = $_COOKIE['autologin_key'];
}
}
/**
* Login as the given user_id.
*/
static function forceLogin(\Db\Connection $db, $user_id) {
User::$instance = User::findUser($db, $user_id);
}
static function logout(\Db\Connection $db) {
unset($_SESSION['user_id']);
unset($_SESSION['user_key']);
unset($_SESSION['user_identity']);
$_SESSION['no_autologin'] = true;
User::$instance = null;
}
static function findUser(\Db\Connection $db, $user_id) {
$q = $db->prepare("SELECT * FROM users WHERE id=? LIMIT 1");
$q->execute(array($user_id));
if ($user = $q->fetch()) {
return new User($user);
} else {
return false;
}
}
function getId() {
return $this->params['id'];
}
function getEmail() {
return $this->params['email'];
}
function setIdentity($identity) {
$_SESSION['user_identity'] = $identity;
}
/**
* Get the identity used to log in this user; persists across requests
* as it is stored in session.
*/
function getIdentity() {
return $_SESSION['user_identity'];
}
/**
* Was this user logged in automatically *in this session*?
*/
function isAutoLoggedIn() {
return $this->is_auto_logged_in;
}
/**
* Delete the given user. Triggers a 'user_deleted' event with the
* current user as an argument.
*/
function delete(\Db\Connection $db) {
// delete all possible identities
$q = $db->prepare("DELETE FROM user_passwords WHERE user_id=?");
$q->execute(array($this->getId()));
$q = $db->prepare("DELETE FROM user_openid_identities WHERE user_id=?");
$q->execute(array($this->getId()));
$q = $db->prepare("DELETE FROM user_oauth2_identities WHERE user_id=?");
$q->execute(array($this->getId()));
$q = $db->prepare("DELETE FROM user_valid_keys WHERE user_id=?");
$q->execute(array($this->getId()));
$q = $db->prepare("DELETE FROM users WHERE id=?");
$q->execute(array($this->getId()));
\Openclerk\Events::trigger('user_deleted', $this);
}
}