|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace WP\OAuth2\Admin\Profile\PersonalTokens; |
| 4 | + |
| 5 | +use WP\OAuth2\PersonalClient; |
| 6 | +use WP\OAuth2\Tokens\Access_Token; |
| 7 | +use WP_Error; |
| 8 | +use WP_User; |
| 9 | + |
| 10 | +const ACCESS_TOKENS_PAGE_SLUG = 'oauth2_personal_tokens'; |
| 11 | + |
| 12 | +function bootstrap() { |
| 13 | + // Personal Access Tokens page. |
| 14 | + add_action( 'admin_action_' . ACCESS_TOKENS_PAGE_SLUG, __NAMESPACE__ . '\\render_page' ); |
| 15 | +} |
| 16 | + |
| 17 | +/** |
| 18 | + * Get the token page URL. |
| 19 | + * |
| 20 | + * @return string |
| 21 | + */ |
| 22 | +function get_page_url( $args = [] ) { |
| 23 | + $url = admin_url( 'profile.php' ); |
| 24 | + $args['action'] = ACCESS_TOKENS_PAGE_SLUG; |
| 25 | + $url = add_query_arg( urlencode_deep( $args ), $url ); |
| 26 | + return $url; |
| 27 | +} |
| 28 | + |
| 29 | +/** |
| 30 | + * Bootstrap the profile page. |
| 31 | + * |
| 32 | + * This sets up the globals for the user page. |
| 33 | + */ |
| 34 | +function bootstrap_profile_page() { |
| 35 | + global $user_id, $submenu_file, $parent_file; |
| 36 | + $user_id = null; |
| 37 | + if ( ! empty( $_REQUEST['user_id'] ) ) { // WPCS: CSRF OK |
| 38 | + $user_id = (int) $_REQUEST['user_id']; |
| 39 | + } |
| 40 | + |
| 41 | + $current_user = wp_get_current_user(); |
| 42 | + if ( ! defined( 'IS_PROFILE_PAGE' ) ) { |
| 43 | + define( 'IS_PROFILE_PAGE', $user_id === $current_user->ID ); |
| 44 | + } |
| 45 | + |
| 46 | + if ( ! $user_id && IS_PROFILE_PAGE ) { |
| 47 | + $user_id = $current_user->ID; |
| 48 | + } |
| 49 | + |
| 50 | + $user = get_user_by( 'id', $user_id ); |
| 51 | + if ( empty( $user ) ) { |
| 52 | + wp_die( __( 'Invalid user ID.' ) ); |
| 53 | + } |
| 54 | + if ( ! current_user_can( 'edit_user', $user_id ) ) { |
| 55 | + wp_die( __( 'Sorry, you are not allowed to edit this user.' ) ); |
| 56 | + } |
| 57 | + |
| 58 | + if ( current_user_can( 'edit_users' ) && ! IS_PROFILE_PAGE ) { |
| 59 | + $submenu_file = 'users.php'; |
| 60 | + } else { |
| 61 | + $submenu_file = 'profile.php'; |
| 62 | + } |
| 63 | + |
| 64 | + if ( current_user_can( 'edit_users' ) ) { |
| 65 | + $parent_file = 'users.php'; |
| 66 | + } else { |
| 67 | + $parent_file = 'profile.php'; |
| 68 | + } |
| 69 | +} |
| 70 | + |
| 71 | +/** |
| 72 | + * Render the access token creation page. |
| 73 | + */ |
| 74 | +function render_page() { |
| 75 | + bootstrap_profile_page(); |
| 76 | + |
| 77 | + $user = get_user_by( 'id', $GLOBALS['user_id'] ); |
| 78 | + |
| 79 | + if ( isset( $_POST['oauth2_action'] ) ) { // WPCS: CSRF OK |
| 80 | + $error = handle_page_action( $user ); |
| 81 | + |
| 82 | + if ( is_wp_error( $error ) ) { |
| 83 | + add_action( 'all_admin_notices', function () use ( $error ) { |
| 84 | + echo '<div class="error"><p>' . esc_html( $error->get_error_message() ) . '</p></div>'; |
| 85 | + } ); |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + $GLOBALS['title'] = __( 'Personal Access Tokens', 'oauth2' ); |
| 90 | + require ABSPATH . 'wp-admin/admin-header.php'; |
| 91 | + |
| 92 | + $tokens = Access_Token::get_for_user( $user ); |
| 93 | + $tokens = array_filter( $tokens, function ( Access_Token $token ) { |
| 94 | + $client = $token->get_client(); |
| 95 | + return ! empty( $client ) && $client instanceof PersonalClient; |
| 96 | + }); |
| 97 | + ?> |
| 98 | + <div class="wrap" id="profile-page"> |
| 99 | + <h1><?php esc_html_e( 'Create a Personal Access Token', 'oauth2' ) ?></h1> |
| 100 | + |
| 101 | + <p><?php esc_html_e( "The WordPress API allows access to your site by external applications. Personal access tokens allow easy access for personal scripts, command line utilities, or during development. Generally, you shouldn't provide these to applications you don't trust, and you should treat them just like passwords.", 'oauth2' ) ?></p> |
| 102 | + |
| 103 | + <form action="" method="POST"> |
| 104 | + <table class="form-table"> |
| 105 | + <tr> |
| 106 | + <th scope="row"> |
| 107 | + <label for="token-name">Token name</label> |
| 108 | + </th> |
| 109 | + <td> |
| 110 | + <input |
| 111 | + class="regular-text" |
| 112 | + id="token-name" |
| 113 | + name="name" |
| 114 | + required="required" |
| 115 | + type="text" |
| 116 | + /> |
| 117 | + |
| 118 | + <p class="description"><?php esc_html_e( 'Give this token a name so you can easily identify it later.', 'oauth2' ) ?></p> |
| 119 | + </td> |
| 120 | + </tr> |
| 121 | + </table> |
| 122 | + |
| 123 | + <input type="hidden" name="oauth2_action" value="create" /> |
| 124 | + |
| 125 | + <?php wp_nonce_field( 'oauth2_personal_tokens.create' ) ?> |
| 126 | + |
| 127 | + <p class="buttons"> |
| 128 | + <button class="button-primary"><?php esc_html_e( 'Generate Token', 'oauth2' ) ?></button> |
| 129 | + </p> |
| 130 | + </form> |
| 131 | + </div> |
| 132 | + <?php |
| 133 | + require ABSPATH . 'wp-admin/admin-footer.php'; |
| 134 | + exit; |
| 135 | +} |
| 136 | + |
| 137 | +/** |
| 138 | + * Handle action from a form. |
| 139 | + */ |
| 140 | +function handle_page_action( WP_User $user ) { |
| 141 | + $action = $_POST['oauth2_action']; // WPCS: CSRF OK |
| 142 | + |
| 143 | + switch ( $action ) { |
| 144 | + case 'create': |
| 145 | + check_admin_referer( 'oauth2_personal_tokens.create' ); |
| 146 | + if ( empty( $_POST['name'] ) ) { |
| 147 | + return new WP_Error( |
| 148 | + 'rest_oauth2_missing_name', |
| 149 | + __( 'Missing name for personal access token.', 'oauth2' ) |
| 150 | + ); |
| 151 | + } |
| 152 | + |
| 153 | + $name = sanitize_text_field( wp_unslash( $_POST['name'] ) ); |
| 154 | + return handle_create( $user, $name ); |
| 155 | + |
| 156 | + default: |
| 157 | + return new WP_Error( |
| 158 | + 'rest_oauth2_invalid_action', |
| 159 | + __( 'Invalid action.', 'oauth2' ) |
| 160 | + ); |
| 161 | + } |
| 162 | +} |
| 163 | + |
| 164 | +/** |
| 165 | + * Handle token creation |
| 166 | + */ |
| 167 | +function handle_create( WP_User $user, $name ) { |
| 168 | + $client = PersonalClient::get_instance(); |
| 169 | + $meta = [ |
| 170 | + 'name' => $name, |
| 171 | + ]; |
| 172 | + $token = $client->issue_token( $user, $meta ); |
| 173 | + |
| 174 | + render_create_success( $user, $token ); |
| 175 | +} |
| 176 | + |
| 177 | +function render_create_success( WP_User $user, $token ) { |
| 178 | + $GLOBALS['title'] = __( 'Personal Access Tokens', 'oauth2' ); |
| 179 | + require ABSPATH . 'wp-admin/admin-header.php'; |
| 180 | + ?> |
| 181 | + |
| 182 | + <div class="wrap" id="profile-page"> |
| 183 | + <h1><?php esc_html_e( 'Token created!', 'oauth2' ) ?></h1> |
| 184 | + <p><?php esc_html_e( "Your token has been created. Make sure to copy it now, as it won't be displayed again!", 'oauth2' ) ?></p> |
| 185 | + |
| 186 | + <pre style="font-size: 2em"><?php echo esc_html( $token->get_key() ) ?></pre> |
| 187 | + |
| 188 | + <p><a href="<?php echo esc_url( get_edit_user_link( $user->ID ) ) ?>"><?php esc_html_e( 'Back to profile', 'oauth2' ) ?></a></p> |
| 189 | + </div> |
| 190 | + |
| 191 | + <?php |
| 192 | + require ABSPATH . 'wp-admin/admin-footer.php'; |
| 193 | + exit; |
| 194 | +} |
0 commit comments