Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

mod/web_services/lib/tokens.php (3 issues)

1
<?php
2
/**
3
 * Library for managing user tokens
4
 */
5
6
/**
7
 * Obtain a token for a user.
8
 *
9
 * @param string $username The username
10
 * @param int    $expire   Minutes until token expires (default is 60 minutes)
11
 *
12
 * @return bool
13
 */
14
function create_user_token($username, $expire = 60) {
15
	$dbprefix = elgg_get_config('dbprefix');
16
	$user = get_user_by_username($username);
17
	$time = time() + 60 * $expire;
18
19
	$token = _elgg_services()->crypto->getRandomString(32, ElggCrypto::CHARS_HEX);
20
21
	if (!$user) {
22
		return false;
23
	}
24
25
	if (insert_data("INSERT into {$dbprefix}users_apisessions
26
				(user_guid, token, expires) values
27
				({$user->guid}, '$token', '$time')
28
				on duplicate key update token='$token', expires='$time'")) {
29
		return $token;
30
	}
31
32
	return false;
33
}
34
35
/**
36
 * Get all tokens attached to a user
37
 *
38
 * @param int $user_guid The user GUID
39
 *
40
 * @return false if none available or array of stdClass objects
41
 * 		(see users_apisessions schema for available variables in objects)
42
 * @since 1.7.0
43
 */
44
function get_user_tokens($user_guid) {
45
	$dbprefix = elgg_get_config('dbprefix');
46
	$user_guid = (int) $user_guid;
47
48
	$tokens = get_data("SELECT * from {$dbprefix}users_apisessions
49
		where user_guid=$user_guid");
50
51
	return $tokens;
52
}
53
54
/**
55
 * Validate a token against a given site.
56
 *
57
 * A token registered with one site can not be used from a
58
 * different apikey(site), so be aware of this during development.
59
 *
60
 * @param string $token The Token.
61
 *
62
 * @return mixed The user id attached to the token if not expired or false.
63
 */
64
function validate_user_token($token) {
65
	$dbprefix = elgg_get_config('dbprefix');
66
	$token = sanitise_string($token);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated: Use query parameters where possible ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

66
	$token = /** @scrutinizer ignore-deprecated */ sanitise_string($token);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
67
	$time = time();
68
69
	$user = get_data_row("SELECT * from {$dbprefix}users_apisessions
70
		where token='$token' and $time < expires");
71
72
	if ($user) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $user of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
73
		return $user->user_guid;
74
	}
75
76
	return false;
77
}
78
79
/**
80
 * Remove user token
81
 *
82
 * @param string $token The token
83
 *
84
 * @return bool
85
 * @since 1.7.0
86
 */
87
function remove_user_token($token) {
88
	$dbprefix = elgg_get_config('dbprefix');
89
	$token = sanitise_string($token);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated: Use query parameters where possible ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

89
	$token = /** @scrutinizer ignore-deprecated */ sanitise_string($token);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
90
91
	return delete_data("DELETE from {$dbprefix}users_apisessions
92
		where token='$token'");
93
}
94
95
/**
96
 * Remove expired tokens
97
 *
98
 * @return bool
99
 * @since 1.7.0
100
 */
101
function remove_expired_user_tokens() {
102
	$dbprefix = elgg_get_config('dbprefix');
103
	$time = time();
104
105
	return delete_data("DELETE from {$dbprefix}users_apisessions
106
		where expires < $time");
107
}
108
109
/**
110
 * The auth.gettoken API.
111
 * This API call lets a user log in, returning an authentication token which can be used
112
 * to authenticate a user for a period of time. It is passed in future calls as the parameter
113
 * auth_token.
114
 *
115
 * @param string $username Username
116
 * @param string $password Clear text password
117
 *
118
 * @return string Token string or exception
119
 * @throws SecurityException
120
 * @access private
121
 */
122
function auth_gettoken($username, $password) {
123
	// check if username is an email address
124
	if (is_email_address($username)) {
125
		$users = get_user_by_email($username);
126
127
		// check if we have a unique user
128
		if (is_array($users) && (count($users) == 1)) {
129
			$username = $users[0]->username;
130
		}
131
	}
132
133
	// validate username and password
134
	if (true === elgg_authenticate($username, $password)) {
135
		$token = create_user_token($username);
136
		if ($token) {
137
			return $token;
138
		}
139
	}
140
141
	throw new SecurityException(elgg_echo('SecurityException:authenticationfailed'));
142
}
143