PluginProbe
WebFinger / trunk
WebFinger vtrunk
4.1.0 trunk 0.5 0.7 0.9 0.9.1 1.0 1.0.1 1.1 1.2 1.3 1.3.1 2.0.0 2.0.1 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 All 36 releases
webfinger / includes / class-user.php

class-user.php in WebFinger trunk, at includes/class-user.php

219 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * User class file.
4 *
5 * @package Webfinger
6 */
7
8 namespace Webfinger;
9
10 /**
11 * User class.
12 *
13 * Handles user-related WebFinger functionality.
14 *
15 * @author Will Norris
16 */
17 class User {
18 /**
19 * Returns a User object by URI.
20 *
21 * @param string $uri The URI to search for.
22 *
23 * @return \WP_User|null The user object or null if not found.
24 *
25 * @uses apply_filters() Uses 'webfinger_user' to filter the user and 'webfinger_user_query' to add custom query-params.
26 */
27 public static function get_user_by_uri( $uri ) {
28 $uri = \urldecode( $uri );
29
30 // Remove wildcards to prevent SQL injection via LIKE queries.
31 $uri = \str_replace( array( '*', '%' ), '', $uri );
32
33 if ( ! $uri || ! is_same_host( $uri ) ) {
34 return null;
35 }
36
37 // Default scheme is acct.
38 $scheme = 'acct';
39 $host = $uri;
40
41 // Try to extract the scheme and the host.
42 if ( \preg_match( '/^([a-zA-Z][a-zA-Z0-9+.-]*):(.+)$/i', $uri, $match ) ) {
43 $scheme = \esc_attr( \strtolower( $match[1] ) );
44 $host = \sanitize_text_field( $match[2] );
45 }
46
47 if ( ! $host || ! $uri ) {
48 return null;
49 }
50
51 $args = self::get_user_query_args( $scheme, $host, $uri );
52
53 if ( null === $args ) {
54 return null;
55 }
56
57 $args = \apply_filters( 'webfinger_user_query', $args, $uri, $scheme );
58
59 if ( empty( $args ) ) {
60 return null;
61 }
62
63 $user_query = new \WP_User_Query( $args );
64 $results = $user_query->get_results();
65
66 return ! empty( $results ) ? $results[0] : null;
67 }
68
69 /**
70 * Get user query arguments based on scheme.
71 *
72 * @param string $scheme The URI scheme.
73 * @param string $host The host/identifier part.
74 * @param string $uri The full URI.
75 *
76 * @return array|null Query arguments or null if user found/invalid.
77 */
78 private static function get_user_query_args( $scheme, $host, $uri ) {
79 switch ( $scheme ) {
80 case 'http':
81 case 'https':
82 $author_id = \url_to_authorid( $uri );
83 if ( $author_id ) {
84 return array(
85 'search' => $author_id,
86 'search_columns' => array( 'ID' ),
87 );
88 }
89 return array(
90 'search' => $uri,
91 'search_columns' => array( 'user_url' ),
92 );
93
94 case 'acct':
95 $pos = \strrpos( $host, '@' );
96 if ( false === $pos ) {
97 return null;
98 }
99 $id = \sanitize_title( \substr( $host, 0, $pos ) );
100 if ( ! $id ) {
101 return null;
102 }
103
104 // First check for custom webfinger_resource meta.
105 $meta_query = new \WP_User_Query(
106 array(
107 'meta_key' => 'webfinger_resource', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
108 'meta_value' => $id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
109 'meta_compare' => '=',
110 'number' => 1,
111 )
112 );
113 $results = $meta_query->get_results();
114 if ( ! empty( $results ) ) {
115 // Return null to signal user was found (handled in caller).
116 return array(
117 'include' => array( $results[0]->ID ),
118 );
119 }
120
121 return array(
122 'search' => $id,
123 'search_columns' => array( 'user_nicename', 'user_login' ),
124 );
125
126 case 'mailto':
127 $email = \sanitize_email( $host );
128 if ( ! $email ) {
129 return null;
130 }
131 return array(
132 'search' => $email,
133 'search_columns' => array( 'user_email' ),
134 );
135
136 default:
137 return array();
138 }
139 }
140
141 /**
142 * Returns a users default user specific part of the WebFinger resource.
143 *
144 * @param mixed $id_or_name_or_object The username, ID or object.
145 *
146 * @return string|null The username or null if not found.
147 */
148 public static function get_username( $id_or_name_or_object ) {
149 $user = \get_user_by_various( $id_or_name_or_object );
150
151 if ( ! $user ) {
152 return null;
153 }
154
155 $custom_resource = \get_user_meta( $user->ID, 'webfinger_resource', true );
156
157 return $custom_resource ?: $user->user_login;
158 }
159
160 /**
161 * Returns a users default WebFinger resource.
162 *
163 * @param mixed $id_or_name_or_object The username, ID or object.
164 * @param bool $with_protocol Whether to include the protocol prefix.
165 *
166 * @return string|null The resource or null if not found.
167 */
168 public static function get_resource( $id_or_name_or_object, $with_protocol = true ) {
169 $user = \get_user_by_various( $id_or_name_or_object );
170
171 if ( ! $user ) {
172 return \apply_filters( 'webfinger_user_resource', null, null );
173 }
174
175 $username = self::get_username( $user );
176 $host = \wp_parse_url( \home_url(), \PHP_URL_HOST );
177 $resource = $username . '@' . $host;
178
179 if ( $with_protocol ) {
180 $resource = 'acct:' . $resource;
181 }
182
183 return \apply_filters( 'webfinger_user_resource', $resource, $user );
184 }
185
186 /**
187 * Returns all WebFinger "resources".
188 *
189 * @param mixed $id_or_name_or_object The username, ID or object.
190 *
191 * @return array The array of resources.
192 */
193 public static function get_resources( $id_or_name_or_object ) {
194 $user = \get_user_by_various( $id_or_name_or_object );
195
196 if ( ! $user ) {
197 return array();
198 }
199
200 $host = \wp_parse_url( \home_url(), \PHP_URL_HOST );
201 $resources = array(
202 self::get_resource( $user ),
203 \get_author_posts_url( $user->ID, $user->user_nicename ),
204 );
205
206 // Add user_login as alias if different from custom resource.
207 $custom_resource = \get_user_meta( $user->ID, 'webfinger_resource', true );
208 if ( $custom_resource && $custom_resource !== $user->user_login ) {
209 $resources[] = 'acct:' . $user->user_login . '@' . $host;
210 }
211
212 if ( $user->user_email && is_same_host( $user->user_email ) ) {
213 $resources[] = 'mailto:' . $user->user_email;
214 }
215
216 return \array_values( \array_unique( \apply_filters( 'webfinger_user_resources', $resources, $user ) ) );
217 }
218 }
219