-
Notifications
You must be signed in to change notification settings - Fork 0
/
apiCall.php
239 lines (222 loc) · 7.1 KB
/
apiCall.php
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
229
230
231
232
233
234
235
236
237
238
239
<?php
/**
* pr0gramm-apiCall Funktion
*
* Eine Funktion, die sich automatisch auf pr0gramm.com einloggt
* um mit den generierten Sessioncookies API Anfragen durchzuführen.
*
* @author RundesBalli <webspam@rundesballi.com>
* @copyright 2022 RundesBalli
* @version 3.0
* @license MIT-License
* @see https://github.com/RundesBalli/pr0gramm-apiCall
*/
/**
* Einbinden der Konfigurationsdatei.
*/
require_once(__DIR__.DIRECTORY_SEPARATOR."config.php");
/**
* pr0gramm-apiCall Funktion
*
* @param string $url Die URL die aufgerufen werden soll.
* @param array $postData Wenn Daten per POST übergeben werden sollen, dann
* müssen sie als Array übergeben werden:
* POSTFIELD=>POSTVALUE
* @param string $authToken Das AuthToken für oAuth, welches als Header
* gesendet wird.
*
* @return array Die API-Response als assoziatives Array.
*/
function apiCall($url, $postData = NULL, $authToken = NULL) {
/**
* Globale Variablen aus der Konfigurationsdatei in die Funktion einbinden.
*/
global $bindTo;
global $userAgent;
global $cookieFile;
/**
* cURL initialisieren
*/
$ch = curl_init();
/**
* Verbindungsoptionen vorbereiten
* @see https://www.php.net/manual/de/function.curl-setopt.php
*/
$options = array(
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => $userAgent,
CURLOPT_INTERFACE => $bindTo,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 10
);
/**
* Postdaten vorbereiten und mit in die Optionen einbinden, sofern durch den
* Funktionsaufruf übergeben und gewünscht.
*/
if($postData !== NULL AND is_array($postData)) {
$data = http_build_query($postData, '', '&', PHP_QUERY_RFC1738);
$options[CURLOPT_POST] = TRUE;
$options[CURLOPT_POSTFIELDS] = $data;
}
/**
* pr0Auth Anfrage an die API mit Token
* (nur für oAuth)
*
* Wenn kein authToken übergeben wurde, dann wird der Cookie eingebunden
*/
if($authToken !== NULL) {
$options[CURLOPT_HTTPHEADER] = array("pr0-api-key: ".$authToken);
$accept403 = TRUE;
} else {
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
$accept403 = FALSE;
}
/**
* Das Optionsarray in den cURL-Handle einfügen
*/
curl_setopt_array($ch, $options);
/**
* Initialisieren der Durchlaufvariablen
*/
$try = 0;
$success = FALSE;
/**
* Versuch die API zu erreichen. Falls zu viele Abfragen erfolgt sind wird
* die Abfrage bis zu 10x wiederholt und dann abgebrochen.
*/
do {
$try++;
if($try > 10) {
die("cURL - Zu viele Versuche - url: ".$url."\n");
}
/**
* Ausführen des cURLs und speichern der Antwort, sowie eventuell
* anfallender Fehler.
*/
$response = curl_exec($ch);
$errNo = curl_errno($ch);
$errStr = curl_error($ch);
if($errNo != 0) {
die("cURL - errno: ".$errNo." - errstr: ".$errStr." - url: ".$url."\n");
}
/**
* Auswerten des HTTP Codes.
*/
$httpCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if($httpCode == 503) {
/**
* Zu viele Anfragen in zu kurzer Zeit.
* 500ms warten, dann nächster Versuch (max. 10 retrys).
*/
usleep(500000);
continue;
} elseif($httpCode == 200 OR $httpCode == 404) {
/**
* Ein nicht mehr vorhandener User wirft einen 404 zurück. Die Anfrage zeigt
* dann in der zurückgegebenen Fehlermeldung, dass der User nicht mehr existiert.
* Daher ist auch ein 404 eine "erfolgreiche" Anfrage.
*/
$success = TRUE;
} elseif($httpCode == 400) {
/**
* Wenn man keinen Bot-Account hat und versucht sich einzuloggen, wirft die API ohne
* übergebene Captcha Daten einen 400 Bad Request. Hier wird drauf hingewiesen, dass
* die Login Credentials nicht ohne Captcha übergeben werden können.
*/
die("Login - Captcha Login erforderlich. Bitte captchaLogin.php ausführen.\n");
} else {
if($httpCode == 403 AND $accept403 == TRUE) {
/**
* Die einzige Situation wo ein HTTP403 zulässig wäre, ist bei der
* Abfrage mit authToken. Wenn mit einem ungültigen authToken angefragt
* wird, dann wirft die API einen 403 zurück, der dann im jeweiligen
* Script abgefangen werden muss.
*/
return NULL;
} else {
/**
* Alle anderen Fehlermeldungen werden direkt ausgegeben und der
* Scriptablauf wird abgebrochen.
*/
die("cURL - httpcode: ".$httpCode." - url: ".$url."\n");
}
}
} while($success == FALSE);
/**
* Beenden des cURL-Handles und speichern der Antwortcookies, sofern
* vorhanden.
*/
curl_close($ch);
/**
* Umwandeln des JSON-Strings aus der Antwort in ein assoziatives Array.
*/
$response = json_decode($response, TRUE);
/**
* Rückgabe des zuvor erzeugten assoziativen Arrays.
*/
return $response;
}
/**
* Wenn das Script per captchaLogin.php aufgerufen wird, ist die Prüfung ob ein
* Login vorliegt irrelevant.
*/
if(!isset($captchaLogin)) {
/**
* Einmalige Prüfung beim Einbinden der Funktion, ob man eingeloggt ist oder
* nicht. Falls nicht wird versucht sich automatisch einzuloggen. (Nur mit
* Bot-Account möglich! Nicht-Bot-Accounts müssen über captchaLogin.php ein-
* geloggt werden.)
*/
$loggedIn = apiCall("https://pr0gramm.com/api/user/loggedin", NULL);
if($loggedIn['loggedIn'] !== TRUE) {
/**
* Der Login wird durchgeführt
*/
$login = apiCall("https://pr0gramm.com/api/user/login", array("name" => $pr0Username, "password" => $pr0Password));
/**
* Wenn der Login nicht erfolgreich war, dann wird noch geprüft wieso dies so
* ist. In jedem Fall wird die Ausführung unterbrochen.
*/
if($login['success'] !== TRUE) {
/**
* Wenn kein Ban vorliegt, dann kann es einerseits an einem falschen
* Passwort, oder daran liegen, dass es sich nicht um einen Bot-Account
* handelt.
*/
if($login['ban'] === NULL) {
if($login['error'] == 'invalidLogin') {
/**
* Falsches Passwort
*/
die("Login - falsches Passwort\n");
} else {
/**
* Unbekannter Fehler mit Ausgabe der Response
*/
die("Login - unbekannter Fehler\n".json_encode($login)."\n");
}
} else {
/**
* Account gesperrt
*/
die("Login - der Account ist gesperrt\n");
}
}
}
/**
* Speicherung der nonce in eine Variable zur weiteren Benutzung.
*/
$fp = fopen($cookieFile, "r");
$read = fread($fp, filesize($cookieFile));
$regex = '/^(?!#)pr0gramm\.com\t.*\tme\t(.*)/m';
preg_match_all($regex, $read, $matches);
$nonce = substr(json_decode(urldecode($matches[1][0]), TRUE)['id'], 0, 16);
/**
* Wenn das Script hier angekommen ist, ist alles in Ordnung. Der Account ist
* mit einer gültigen Sitzung eingeloggt, die nonce steht zur Verfügung und es
* kann losgehen.
*/
}
?>