Skip to content

Commit f52d49b

Browse files
committed
Split auth code to new object
1 parent 8c99784 commit f52d49b

File tree

3 files changed

+192
-13
lines changed

3 files changed

+192
-13
lines changed

inc/class-client.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace WP\OAuth2;
44

55
use WP\OAuth2\Tokens\Access_Token;
6+
use WP\OAuth2\Tokens\Authorization_Code;
67
use WP_Error;
78
use WP_Post;
89
use WP_Query;
@@ -235,18 +236,17 @@ public function check_redirect_uri( $uri ) {
235236
* @return string|WP_Error
236237
*/
237238
public function generate_authorization_code( WP_User $user ) {
238-
$code = wp_generate_password( static::AUTH_CODE_LENGTH, false );
239-
$meta_key = static::AUTH_CODE_KEY_PREFIX . $code;
240-
$data = array(
241-
'user' => $user->ID,
242-
'expiration' => static::AUTH_CODE_AGE,
243-
);
244-
$result = add_post_meta( $this->get_post_id(), wp_slash( $meta_key ), wp_slash( $data ), true );
245-
if ( ! $result ) {
246-
return new WP_Error();
247-
}
239+
return Authorization_Code::create( $this, $user );
240+
}
248241

249-
return $code;
242+
/**
243+
* Get data stored for an authorization code.
244+
*
245+
* @param string $code Authorization code to fetch.
246+
* @return array|WP_Error Data if available, error if invalid code.
247+
*/
248+
public function get_authorization_code( $code ) {
249+
return Authorization_Code::get_by_code( $this, $code );
250250
}
251251

252252
/**
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
3+
namespace WP\OAuth2\Tokens;
4+
5+
use WP_Error;
6+
use WP_Http;
7+
use WP\OAuth2\Client;
8+
use WP_User;
9+
10+
/**
11+
* Authorization Code object.
12+
*
13+
* Not technically a token, but similar.
14+
*/
15+
class Authorization_Code {
16+
const KEY_PREFIX = '_oauth2_authcode_';
17+
const KEY_LENGTH = 12;
18+
const MAX_AGE = 600; // 10 * MINUTE_IN_SECONDS
19+
20+
/**
21+
* Actual code.
22+
*
23+
* @var string
24+
*/
25+
protected $code;
26+
27+
/**
28+
* Associated API client.
29+
*
30+
* @var Client
31+
*/
32+
protected $client;
33+
34+
public function __construct( Client $client, $code ) {
35+
$this->client = $client;
36+
$this->code = $code;
37+
}
38+
39+
/**
40+
* Get the actual code.
41+
*
42+
* @return string Authorization code for passing to client.
43+
*/
44+
public function get_code() {
45+
return $this->code;
46+
}
47+
48+
/**
49+
* Get meta key.
50+
*
51+
* Authorization codes are stored as post meta on the client.
52+
*
53+
* @return string
54+
*/
55+
protected function get_meta_key() {
56+
return static::KEY_PREFIX . $this->code;
57+
}
58+
59+
/**
60+
* Get meta value.
61+
*
62+
* @return array|null Data if available, or null if code does not exist.
63+
*/
64+
protected function get_value() {
65+
$data = get_post_meta( $this->client->get_post_id(), wp_slash( $this->get_meta_key() ), false );
66+
if ( empty( $data ) ) {
67+
return null;
68+
}
69+
70+
return $data[0];
71+
}
72+
73+
/**
74+
* Get the user for the authorization code.
75+
*
76+
* @return WP_User|WP_Error User object, or error if data is not valid.
77+
*/
78+
public function get_user() {
79+
$value = $this->get_value();
80+
if ( empty( $value ) || empty( $value['user'] ) ) {
81+
return new WP_Error(
82+
'oauth2.tokens.authorization_code.get_user.invalid_data',
83+
__( 'Authorization code data is not valid.', 'oauth2' )
84+
);
85+
}
86+
87+
return get_user_by( 'id', (int) $value['user'] );
88+
}
89+
90+
public function get_expiration() {
91+
$value = $this->get_value();
92+
if ( empty( $value ) || empty( $value['expiration'] ) ) {
93+
return new WP_Error(
94+
'oauth2.tokens.authorization_code.get_user.invalid_data',
95+
__( 'Authorization code data is not valid.', 'oauth2' )
96+
);
97+
}
98+
99+
return $value['expiration'];
100+
}
101+
102+
/**
103+
* Validate the code for use.
104+
*
105+
* @param array $args Other request arguments to validate.
106+
* @return bool|WP_Error True if valid, error describing problem otherwise.
107+
*/
108+
public function validate( $args = array() ) {
109+
$expiration = $this->get_expiration();
110+
$now = time();
111+
if ( $expiration <= $now ) {
112+
return new WP_Error(
113+
'oauth2.tokens.authorization_code.validate.expired',
114+
__( 'Authorization code has expired.', 'oauth2' ),
115+
array(
116+
'status' => WP_Http::BAD_REQUEST,
117+
'expiration' => $expiration,
118+
'time' => $now,
119+
)
120+
);
121+
}
122+
123+
return true;
124+
}
125+
126+
/**
127+
* Delete the authorization code.
128+
*
129+
* @return bool|WP_Error True if deleted, error otherwise.
130+
*/
131+
public function delete() {
132+
$result = delete_post_meta( $this->client->get_post_id(), wp_slash( $this->get_meta_key() ) );
133+
if ( ! $result ) {
134+
return new WP_Error(
135+
'oauth2.tokens.authorization_code.delete.could_not_delete',
136+
__( 'Unable to delete authorization code.', 'oauth2' )
137+
);
138+
}
139+
140+
return true;
141+
}
142+
143+
public static function get_by_code( Client $client, $code ) {
144+
$key = static::KEY_PREFIX . $code;
145+
$value = get_post_meta( $client->get_post_id(), wp_slash( $key ), false );
146+
if ( empty( $value ) ) {
147+
return new WP_Error(
148+
'oauth2.client.check_authorization_code.invalid_code',
149+
__( 'Authorization code is not valid for the specified client.', 'oauth2' ),
150+
array(
151+
'status' => WP_Http::NOT_FOUND,
152+
'client' => $client->get_id(),
153+
'code' => $code,
154+
)
155+
);
156+
}
157+
158+
return new static( $client, $code );
159+
}
160+
161+
public static function create( Client $client, WP_User $user ) {
162+
$code = wp_generate_password( static::KEY_LENGTH, false );
163+
$meta_key = static::KEY_PREFIX . $code;
164+
$data = array(
165+
'user' => (int) $user->ID,
166+
'expiration' => time() + static::MAX_AGE,
167+
);
168+
$result = add_post_meta( $client->get_post_id(), wp_slash( $meta_key ), wp_slash( $data ), true );
169+
if ( ! $result ) {
170+
return new WP_Error(
171+
'oauth2.tokens.authorization_code.create.could_not_create',
172+
__( 'Unable to create authorization code.', 'oauth2' )
173+
);
174+
}
175+
176+
return new static( $client, $code );
177+
}
178+
}

inc/types/class-authorization-code.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ protected function handle_authorization_submission( $submit, Client $client, $da
2323
switch ( $submit ) {
2424
case 'authorize':
2525
// Generate authorization code and redirect back.
26-
$code = $client->generate_authorization_code();
26+
$user = wp_get_current_user();
27+
$code = $client->generate_authorization_code( $user );
2728
if ( is_wp_error( $code ) ) {
2829
return $code;
2930
}
3031

3132
$redirect_args = array(
32-
'code' => $code,
33+
'code' => $code->get_code(),
3334
);
3435
break;
3536

0 commit comments

Comments
 (0)