Skip to content

Commit 497bbe5

Browse files
committed
Use AJAX to revoke GitHub app token
Fixes #303
2 parents 3b70723 + a1b251d commit 497bbe5

File tree

3 files changed

+129
-29
lines changed

3 files changed

+129
-29
lines changed

SourceGithub/SourceGithub.php

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,41 @@ public function routes( $p_event_name, $p_event_args ) {
6565
$t_app->group(
6666
plugin_route_group(),
6767
function() use ( $t_app, $t_plugin ) {
68+
$t_app->delete( '/{id}/token', [$t_plugin, 'route_token_revoke'] );
6869
$t_app->post( '/{id}/webhook', [$t_plugin, 'route_webhook'] );
6970
}
7071
);
7172
}
7273

74+
/**
75+
* RESTful route to revoke GitHub application token
76+
*
77+
* @param Slim\Http\Request $p_request
78+
* @param Slim\Http\Response $p_response
79+
* @param array $p_args
80+
*
81+
* @return Slim\Http\Response
82+
*/
83+
public function route_token_revoke( $p_request, $p_response, $p_args ) {
84+
# Make sure the given repository exists
85+
$t_repo_id = isset( $p_args['id'] ) ? $p_args['id'] : $p_request->getParam( 'id' );
86+
if( !SourceRepo::exists( $t_repo_id ) ) {
87+
return $p_response->withStatus( HTTP_STATUS_BAD_REQUEST, 'Invalid Repository Id' );
88+
}
89+
90+
# Check that the repo is of GitHub type
91+
$t_repo = SourceRepo::load( $t_repo_id );
92+
if( $t_repo->type != $this->type ) {
93+
return $p_response->withStatus( HTTP_STATUS_BAD_REQUEST, "Id $t_repo_id is not a GitHub repository" );
94+
}
95+
96+
# Clear the token
97+
unset( $t_repo->info['hub_app_access_token'] );
98+
$t_repo->save();
99+
100+
return $p_response->withStatus( HTTP_STATUS_NO_CONTENT );
101+
}
102+
73103
/**
74104
* RESTful route to create GitHub checkin webhook
75105
*
@@ -271,49 +301,63 @@ public function update_repo_form( $p_repo ) {
271301
<tr>
272302
<td class="category"><?php echo plugin_lang_get( 'hub_app_client_id' ) ?></td>
273303
<td>
274-
<input type="text" name="hub_app_client_id" maxlength="250" size="40" value="<?php echo string_attribute( $t_hub_app_client_id ) ?>"/>
304+
<input name="hub_app_client_id" id="hub_app_client_id"
305+
type="text" maxlength="250" size="40"
306+
value="<?php echo string_attribute( $t_hub_app_client_id ) ?>"
307+
data-original="<?php echo string_attribute( $t_hub_app_client_id ) ?>"
308+
/>
275309
</td>
276310
</tr>
277311

278312
<tr>
279313
<td class="category"><?php echo plugin_lang_get( 'hub_app_secret' ) ?></td>
280314
<td>
281-
<input type="text" name="hub_app_secret" maxlength="250" size="40" value="<?php echo string_attribute( $t_hub_app_secret ) ?>"/>
315+
<input name="hub_app_secret" id="hub_app_secret"
316+
type="text" maxlength="250" size="40"
317+
value="<?php echo string_attribute( $t_hub_app_secret ) ?>"
318+
data-original="<?php echo string_attribute( $t_hub_app_secret ) ?>"
319+
/>
282320
</td>
283321
</tr>
284322

285323
<tr>
286324
<td class="category"><?php echo plugin_lang_get( 'hub_app_access_token' ) ?></td>
287325
<td>
288-
<?php
289-
$t_hide_webhook_create = true;
326+
<div id="id_secret_missing" class="hidden">
327+
<?php echo plugin_lang_get( 'hub_app_client_id_secret_missing' ); ?>
328+
</div>
290329

291-
if( empty( $t_hub_app_client_id ) || empty( $t_hub_app_secret ) ) {
292-
echo plugin_lang_get( 'hub_app_client_id_secret_missing' );
293-
} elseif( empty( $t_hub_app_access_token ) ) {
294-
print_link( $this->oauth_authorize_uri( $p_repo ), plugin_lang_get( 'hub_app_authorize' ) );
295-
} else {
296-
$t_hide_webhook_create = false;
297-
echo plugin_lang_get( 'hub_app_authorized' );
298-
# @TODO This would be better with an AJAX, but this will do for now
299-
?>
300-
<input type="submit" class="btn btn-xs btn-primary btn-white btn-round" name="revoke" value="<?php echo plugin_lang_get( 'hub_app_revoke' ) ?>"/>
330+
<div id="token_missing" class="sourcegithub_token hidden">
301331
<?php
302-
}
332+
print_small_button(
333+
$this->oauth_authorize_uri( $p_repo ),
334+
plugin_lang_get( 'hub_app_authorize' )
335+
);
336+
?>
337+
</div>
338+
339+
<div id="token_authorized" class="sourcegithub_token hidden">
340+
<input name="hub_app_access_token" id="hub_app_access_token"
341+
type="hidden" maxlength="250" size="40"
342+
value="<?php echo string_attribute( $t_hub_app_access_token ) ?>"
343+
/>
344+
<?php echo plugin_lang_get( 'hub_app_authorized' ); ?>&nbsp;
345+
<button id="btn_auth_revoke" type="button"
346+
class="btn btn-primary btn-white btn-round btn-sm"
347+
data-token-set="<?php echo $t_hub_app_access_token ? 'true' : 'false' ?>"
348+
>
349+
<?php echo plugin_lang_get( 'hub_app_revoke' ) ?>
350+
</button>
351+
</div>
303352

304-
# Only show the webhook creation div when the app has been authorized
305-
if( $t_hide_webhook_create ) {
306-
$t_webhook_create_css = ' class="hidden"';
307-
}
308-
?>
309353
</td>
310354
</tr>
311355

312356
<tr>
313357
<td class="category"><?php echo plugin_lang_get( 'hub_webhook_secret' ) ?></td>
314358
<td>
315359
<input type="text" name="hub_webhook_secret" maxlength="250" size="40" value="<?php echo string_attribute( $t_hub_webhook_secret ) ?>"/>
316-
<div id="webhook_create"<?php echo $t_webhook_create_css; ?>>
360+
<div id="webhook_create" class="sourcegithub_token hidden">
317361
<div class="space-2"></div>
318362
<button type="button" class="btn btn-primary btn-white btn-round btn-sm">
319363
<?php echo plugin_lang_get( 'webhook_create' ); ?>
@@ -337,12 +381,6 @@ public function update_repo_form( $p_repo ) {
337381
}
338382

339383
public function update_repo( $p_repo ) {
340-
# Revoking previously authorized Github access token
341-
if( gpc_isset( 'revoke' ) ) {
342-
unset( $p_repo->info['hub_app_access_token'] );
343-
return $p_repo;
344-
}
345-
346384
$f_hub_username = gpc_get_string( 'hub_username' );
347385
$f_hub_reponame = gpc_get_string( 'hub_reponame' );
348386
$f_hub_app_client_id = gpc_get_string( 'hub_app_client_id' );
@@ -651,7 +689,16 @@ private function oauth_authorize_uri( $p_repo ) {
651689
}
652690

653691
if ( !empty( $t_hub_app_client_id ) && !empty( $t_hub_app_secret ) ) {
654-
return 'https://github.com/login/oauth/authorize?client_id=' . $t_hub_app_client_id . '&redirect_uri=' . urlencode(config_get('path') . 'plugin.php?page=SourceGithub/oauth_authorize&id=' . $p_repo->id ) . '&scope=repo';
692+
$t_redirect_uri = config_get( 'path' )
693+
. plugin_page( 'oauth_authorize', true ) . '&'
694+
. http_build_query( array( 'id' => $p_repo->id ) );
695+
$t_param = array(
696+
'client_id' => $t_hub_app_client_id,
697+
'redirect_uri' => $t_redirect_uri,
698+
'scope' => 'repo',
699+
'allow_signup' => false,
700+
);
701+
return 'https://github.com/login/oauth/authorize?' . http_build_query( $t_param );
655702
} else {
656703
return '';
657704
}

SourceGithub/files/sourcegithub.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,61 @@ SourceGithub.rest_api = function(endpoint) {
1818
};
1919

2020
jQuery(document).ready(function($) {
21+
$('#hub_app_client_id, #hub_app_secret').change(set_visibility);
22+
$('#btn_auth_revoke').click(revoke_token);
2123
$('#webhook_create > button').click(webhook_create);
2224

25+
// The PHP code initially hides all token authorization elements using the.
26+
// 'hidden' class, which we need to remove so we can set visibility using
27+
// show/hide functions
28+
set_visibility();
29+
$('.sourcegithub_token, #id_secret_missing').removeClass('hidden');
30+
31+
function set_visibility() {
32+
var div_id_secret_missing = $('#id_secret_missing');
33+
var client_id = $('#hub_app_client_id');
34+
var secret = $('#hub_app_secret');
35+
36+
// If Client ID and secret are set and equal to the recorded values
37+
// for the repository, we hide the information message and display the
38+
// authorize or revoke button and authorization status as needed.
39+
if ( client_id.val() !== ''
40+
&& client_id.val() === client_id.data('original')
41+
&& secret.val() !== ''
42+
&& secret.val() === secret.data('original')
43+
) {
44+
var div_token_authorized = $('#token_authorized');
45+
var div_token_missing = $('#token_missing');
46+
var div_webhook = $('#webhook_create');
47+
var token = div_token_authorized.children('input');
48+
49+
div_id_secret_missing.hide();
50+
if (token.val() !== '') {
51+
div_token_authorized.add(div_webhook).show();
52+
div_token_missing.hide();
53+
} else {
54+
div_token_authorized.add(div_webhook).hide();
55+
div_token_missing.show();
56+
}
57+
} else {
58+
div_id_secret_missing.show();
59+
$('.sourcegithub_token').hide();
60+
}
61+
}
62+
63+
function revoke_token() {
64+
var repo_id = $('#repo_id').val();
65+
66+
$.ajax({
67+
type: 'DELETE',
68+
url: SourceGithub.rest_api(repo_id + '/token'),
69+
success: function(data, textStatus, xhr) {
70+
$('#hub_app_access_token').val('');
71+
set_visibility();
72+
}
73+
});
74+
}
75+
2376
function webhook_create() {
2477
var repo_id = $('#repo_id').val();
2578
var status_icon = $('#webhook_status > i');

SourceGithub/lang/strings_english.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ $s_plugin_SourceGithub_hub_reponame = 'GitHub Repository Name<br/><span class="s
1313
$s_plugin_SourceGithub_hub_app_client_id = 'GitHub Application Client ID<br><span class="small">This is required for private repositories and also allows to get around the <a href="https://developer.github.com/v3/#rate-limiting">Rate Limit</a> when importing data.<br>Create a new <a href="https://github.com/settings/applications">GitHub Application</a> if needed.</span>';
1414
$s_plugin_SourceGithub_hub_app_secret = 'GitHub Application Secret';
1515
$s_plugin_SourceGithub_hub_app_access_token = 'GitHub Application Access Token';
16-
$s_plugin_SourceGithub_hub_webhook_secret = 'GitHub Webhook Secret';
16+
$s_plugin_SourceGithub_hub_webhook_secret = 'GitHub Webhook Secret<br/><span class="small">This must match the <em>Secret</em> set in the webhook\'s definition, and is used to validate the payload\'s signature.</span>';
1717
$s_plugin_SourceGithub_master_branch = 'Primary Branches<br/><span class="small">(comma-separated list or "*" for all branches)</span>';
1818

1919
$s_plugin_SourceGithub_hub_app_client_id_secret_missing = '<span class="small">You must first enter the GitHub Application <em>Client ID</em> &amp; <em>Secret</em> and update the repository before you can authorize.</span>';

0 commit comments

Comments
 (0)