summaryrefslogtreecommitdiff
blob: 0869257d0e100ef9f800b8cb4eb5c4a20213a193 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<?php

if ( PHP_SAPI !== 'cli' ) {
	die( "CLI-only test script\n" );
}

/**
 * Testing integration with MediaWiki OAuth Extension
 *
 * The current extension follows OAuth 1.0a spec and while the
 * extension works, you have to be aware of a few quirks.
 *
 * This sample is there to help you work your mind through the OAuth
 * process. Its assuming your MediaWiki installation has this extension
 * installed so you can become your own OAuth service provider. In other
 * words, users in the wiki will be able to make various APIs calls
 * to this wiki using OAuth tokens.
 *
 * PLEASE NOTE:
 *
 *   Remember that OAuth 1.0 expects that the GET Request parameters
 *   are sorted in some order, then to have it hashed.
 *
 *   In relation to MW; One known caveat is that the `$baseurl` has to
 *   be calling to your MediaWiki's `index.php` with
 *   `index.php?title=Special:OAuth` directly.
 *
 *   Otherwise the extension will return an URL that way, and will break the hash
 *   signature and you will get an error.
 */

require __DIR__ . '/../lib/OAuth.php';

/**
 * Local to this example
 *
 * Whether you want to also see
 * the objects being sent to the wire.
 */
$moreVerbose = false;

/**
 * Consumer key
 *
 * This is the application key you would
 * get from the application you want to connect
 * with your MediaWiki installation.
 */
$consumerKey = 'dpf43f3p2l4k3l03';

/**
 * Secret
 *
 * This is the generated secret key
 * that you would get when you ask.
 */
$consumerSecret = 'kd94hf93k423kf44';

/**
 * Base URL
 *
 * Set to your MediaWiki address with "index.php?title=Special:OAuth".
 *
 * Remember that its a known limitation that you cannot use pretty URLs
 * in this context.
 *
 * Ideally, you should have a SSL VirtualHost, but this test would not
 * fail if you don't have one yet.
 */
$baseurl = 'https://localhost/w/index.php?title=Special:OAuth';

/**
 * Request token (a.k.a. the first step)
 *
 * The first step starts at "Special:OAuth/initiate" from the extension.
 *
 * Note that the `oauth_callback=oob` means "Out Of Band", and we currently
 * cannot generate an URL based on headers, but from contents of the Response
 * body (hence "out of band").
 *
 * This is due to the fact that the way the extension is made, it'll return
 * something in the Response body that will need to create the link and
 * make the user validate, and get the token.
 */
$request_token_url = $baseurl . '/initiate&format=json&oauth_callback=oob';

/**
 * Validate token (a.k.a. the 2nd step)
 *
 * This is the URL you use to send back to the application
 * when that the connecting application gives you when the
 * user accepted the request.
 */
$validate_token_url = $baseurl . '/token&format=json';

/**
 * You should not need to edit anything else beyond this point
 */

// This is to allow you to work without SSL locally
$baseUrlIsSsl = (bool)preg_match( '/^https/i', $baseurl );

print <<<HELPTEXT

    Testing OAuth integration with MediaWiki.

HELPTEXT;

/**
 * First step
 */
$c = new OAuthConsumer( $consumerKey, $consumerSecret );
$parsed = parse_url( $request_token_url );
$params = [];
parse_str( $parsed['query'], $params );
$req_req = OAuthRequest::from_consumer_and_token( $c, null, "GET", $request_token_url, $params );
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
$sig_method = $hmac_method;
$req_req->sign_request( $sig_method, $c, null );

print <<<HELPTEXT


    First step, asking for an URL to send the user to.


HELPTEXT;

echo "Calling: $req_req" . PHP_EOL;

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, (string)$req_req );
if ( $baseUrlIsSsl === true ) {
	curl_setopt( $ch, CURLOPT_PORT, 443 );
	curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
}
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
if ( $moreVerbose === true ) {
	curl_setopt( $ch, CURLOPT_VERBOSE, 1 );
}
$data = curl_exec( $ch );

if ( !$data ) {
	die( 'cURL error: ' . curl_error( $ch ) );
}

$token = json_decode( $data );

// @codingStandardsIgnoreStart
print <<<HELPTEXT

	Response body should be a JSON object with three keys:
		- key
		- secret
		- oauth_callback_confirmed

	You got: {$data}


	************************

	Step two!

	So far, we made one request and we should have what we need to get acknowledgement from the end user.

	In order to continue, we have to ask the user for a permission. With what we just did, it gave us a one-time URL to send our user to.

	The process can continue only if the user accepted it. Once accepted, MediaWiki's OAuth Extension creates an "oauth_verifier" string that you need to give for the next step.

	Now, WITH YOUR WEB BROWSER, follow this link and pass through the validation.

	Link: {$baseurl}/authorize&oauth_token={$token->key}&oauth_consumer_key={$consumerKey}


HELPTEXT;
// @codingStandardsIgnoreEnd

// ACCESS TOKEN
print 'What was the "verification value" the MediaWiki installation gave?' . PHP_EOL;
$fh = fopen( "php://stdin", "r" );
$line = fgets( $fh );

/**
 * Second step
 */
$rc = new OAuthConsumer( $token->key, $token->secret );
$parsed = parse_url( $validate_token_url );
parse_str( $parsed['query'], $params );
$params['oauth_verifier'] = trim( $line );

$acc_req = OAuthRequest::from_consumer_and_token( $c, $rc, "GET", $validate_token_url, $params );
$acc_req->sign_request( $sig_method, $c, $rc );

print <<<HELPTEXT

    Going to validate token with another Request to the backend...

HELPTEXT;

echo "Calling: $acc_req" . PHP_EOL;

unset( $ch );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, (string)$acc_req );
if ( $baseUrlIsSsl === true ) {
	curl_setopt( $ch, CURLOPT_PORT, 443 );
	curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
}
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
if ( $moreVerbose === true ) {
	curl_setopt( $ch, CURLOPT_VERBOSE, 1 );
}
$data = curl_exec( $ch );
if ( !$data ) {
	echo 'Curl error: ' . curl_error( $ch );
}

print <<<HELPTEXT

    If all worked well, you should have a JSON object with two keys: key, secret.

    You got:

HELPTEXT;

var_dump( $data );